diff options
-rw-r--r-- | contrib/sendmail/cf/m4/cfhead.m4 | 76 | ||||
-rw-r--r-- | contrib/sendmail/mail.local/mail.local.8 | 33 | ||||
-rw-r--r-- | contrib/sendmail/mail.local/mail.local.c | 618 | ||||
-rw-r--r-- | contrib/sendmail/mailstats/mailstats.c | 205 | ||||
-rw-r--r-- | contrib/sendmail/makemap/makemap.c | 274 | ||||
-rw-r--r-- | contrib/sendmail/praliases/praliases.c | 154 | ||||
-rw-r--r-- | contrib/sendmail/rmail/rmail.c | 186 | ||||
-rw-r--r-- | contrib/sendmail/smrsh/smrsh.8 | 10 | ||||
-rw-r--r-- | contrib/sendmail/smrsh/smrsh.c | 143 | ||||
-rw-r--r-- | contrib/sendmail/src/aliases.5 | 4 | ||||
-rw-r--r-- | contrib/sendmail/src/conf.c | 2518 | ||||
-rw-r--r-- | contrib/sendmail/src/conf.h | 2733 | ||||
-rw-r--r-- | contrib/sendmail/src/err.c | 421 | ||||
-rw-r--r-- | contrib/sendmail/src/headers.c | 466 | ||||
-rw-r--r-- | contrib/sendmail/src/mailq.1 | 6 | ||||
-rw-r--r-- | contrib/sendmail/src/mci.c | 522 | ||||
-rw-r--r-- | contrib/sendmail/src/savemail.c | 622 | ||||
-rw-r--r-- | contrib/sendmail/src/sendmail.8 | 78 | ||||
-rw-r--r-- | contrib/sendmail/vacation/vacation.1 | 60 |
19 files changed, 3455 insertions, 5674 deletions
diff --git a/contrib/sendmail/cf/m4/cfhead.m4 b/contrib/sendmail/cf/m4/cfhead.m4 index db4df2f..a857c6c 100644 --- a/contrib/sendmail/cf/m4/cfhead.m4 +++ b/contrib/sendmail/cf/m4/cfhead.m4 @@ -24,6 +24,10 @@ include(TEMPFILE)dnl syscmd(rm -f TEMPFILE)dnl')', `dnl') ##### ###################################################################### +##### +##### DO NOT EDIT THIS FILE! Only edit the source .mc file. +##### +###################################################################### ###################################################################### divert(-1) @@ -47,8 +51,6 @@ define(`OSTYPE', ## helpful functions define(`lower', `translit(`$1', `ABCDEFGHIJKLMNOPQRSTUVWXYZ', `abcdefghijklmnopqrstuvwx')') define(`strcasecmp', `ifelse(lower($1), lower($2), `1', `0')') -## new FEATUREs -define(`_DNSBL_R_',`') ## access to further arguments in FEATURE/HACK define(`_ACC_ARG_1_',`$1') define(`_ACC_ARG_2_',`$2') @@ -102,14 +104,21 @@ dnl in MAILER.m4: _MODMF_(LMF,`LOCAL') dnl ---------------------------------------- define(`MAILER', `define(`_M_N_', `ifelse(`$2', `', `$1', `$2')')dnl -ifdef(_MAILER_`'_M_N_`'_, `dnl`'', +ifdef(`_MAILER_DEFINED_', `', `define(`_MAILER_DEFINED_', `1')')dnl +ifdef(_MAILER_`'_M_N_`'_, +`errprint(`*** ERROR: MAILER('_M_N_`) already included +')', `define(_MAILER_`'_M_N_`'_, `')define(`_ARG_', `$2')define(`_ARGS_', `shift($@)')PUSHDIVERT(7)include(_CF_DIR_`'mailer/$1.m4)POPDIVERT`'')') define(`DOMAIN', `PUSHDIVERT(-1)define(`_ARG_', `$2')include(_CF_DIR_`'domain/$1.m4)POPDIVERT`'') -define(`FEATURE', `PUSHDIVERT(-1)define(`_ARG_', `$2')define(`_ARGS_', `shift($@)')include(_CF_DIR_`'feature/$1.m4)POPDIVERT`'') +define(`FEATURE', `PUSHDIVERT(-1)ifdef(`_MAILER_DEFINED_',`errprint(`*** ERROR: FEATURE() should be before MAILER() +')')define(`_ARG_', `$2')define(`_ARGS_', `shift($@)')include(_CF_DIR_`'feature/$1.m4)POPDIVERT`'') define(`HACK', `PUSHDIVERT(-1)define(`_ARG_', `$2')define(`_ARGS_', `shift($@)')include(_CF_DIR_`'hack/$1.m4)POPDIVERT`'') define(`_DPO_',`') define(`DAEMON_OPTIONS', `define(`_DPO_', defn(`_DPO_') O DaemonPortOptions=`$1')') +define(`_CPO_',`') +define(`CLIENT_OPTIONS', `define(`_CPO_', defn(`_CPO_') +O ClientPortOptions=`$1')') define(`_MAIL_FILTERS_', `') define(`MAIL_FILTER', `define(`_MAIL_FILTERS_', defn(`_MAIL_FILTERS_') X`'$1`, '`$2')') @@ -117,7 +126,10 @@ define(`INPUT_MAIL_FILTER', `MAIL_FILTER(`$1', `$2') ifelse(defn(`confINPUT_MAIL_FILTERS')X, `X', `define(`confINPUT_MAIL_FILTERS', $1)', `define(`confINPUT_MAIL_FILTERS', defn(`confINPUT_MAIL_FILTERS')`, '`$1')')') -define(`CF_LEVEL', `9')dnl +define(`_QUEUE_GROUP_', `') +define(`QUEUE_GROUP', `define(`_QUEUE_GROUP_', defn(`_QUEUE_GROUP_') +Q`'$1`, '`$2')') +define(`CF_LEVEL', `10')dnl define(`VERSIONID', ``##### $1 #####'') define(`LOCAL_RULE_0', `divert(3)') define(`LOCAL_RULE_1', @@ -140,6 +152,36 @@ define(`LOCAL_RULESETS', `divert(9) ') +define(`LOCAL_SRV_FEATURES', +`define(`_LOCAL_SRV_FEATURES_') +ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_SRV_FEATURES +')') +divert(9) +SLocal_srv_features') +define(`LOCAL_TRY_TLS', +`define(`_LOCAL_TRY_TLS_') +ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_TRY_TLS +')') +divert(9) +SLocal_try_tls') +define(`LOCAL_TLS_RCPT', +`define(`_LOCAL_TLS_RCPT_') +ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_TLS_RCPT +')') +divert(9) +SLocal_tls_rcpt') +define(`LOCAL_TLS_CLIENT', +`define(`_LOCAL_TLS_CLIENT_') +ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_TLS_CLIENT +')') +divert(9) +SLocal_tls_client') +define(`LOCAL_TLS_SERVER', +`define(`_LOCAL_TLS_SERVER_') +ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_TLS_SERVER +')') +divert(9) +SLocal_tls_server') define(`LOCAL_RULE_3', `divert(2)') define(`LOCAL_CONFIG', `divert(6)') define(`MAILER_DEFINITIONS', `divert(7)') @@ -150,17 +192,19 @@ define(`DOL', ``$'$1') define(`SITECONFIG', `CONCAT(D, $3, $2) define(`_CLASS_$3_', `')dnl -ifelse($3, U, Cw$2 $2.UUCP, `dnl') +ifelse($3, U, C{w}$2 $2.UUCP, `dnl') define(`SITE', `ifelse(CONCAT($'2`, $3), SU, CONCAT(CY, $'1`), CONCAT(C, $3, $'1`))') sinclude(_CF_DIR_`'siteconfig/$1.m4)') define(`EXPOSED_USER', `PUSHDIVERT(5)C{E}$1 POPDIVERT`'dnl`'') -ifdef(`_FFR_EXPOSED_USER_FILE', `define(`EXPOSED_USER_FILE', `PUSHDIVERT(5)F{E}$1 -POPDIVERT`'dnl`'')', `dnl') +define(`EXPOSED_USER_FILE', `PUSHDIVERT(5)F{E}$1 +POPDIVERT`'dnl`'') define(`LOCAL_USER', `PUSHDIVERT(5)C{L}$1 POPDIVERT`'dnl`'') +define(`LOCAL_USER_FILE', `PUSHDIVERT(5)F{L}$1 +POPDIVERT`'dnl`'') define(`MASQUERADE_AS', `define(`MASQUERADE_NAME', $1)') define(`MASQUERADE_DOMAIN', `PUSHDIVERT(5)C{M}$1 POPDIVERT`'dnl`'') @@ -168,6 +212,8 @@ define(`MASQUERADE_EXCEPTION', `PUSHDIVERT(5)C{N}$1 POPDIVERT`'dnl`'') define(`MASQUERADE_DOMAIN_FILE', `PUSHDIVERT(5)F{M}$1 POPDIVERT`'dnl`'') +define(`MASQUERADE_EXCEPTION_FILE', `PUSHDIVERT(5)F{N}$1 +POPDIVERT`'dnl`'') define(`LOCAL_DOMAIN', `PUSHDIVERT(5)C{w}$1 POPDIVERT`'dnl`'') define(`CANONIFY_DOMAIN', `PUSHDIVERT(5)C{Canonify}$1 @@ -182,6 +228,10 @@ define(`LDAPROUTE_DOMAIN', `PUSHDIVERT(5)C{LDAPRoute}$1 POPDIVERT`'dnl`'') define(`LDAPROUTE_DOMAIN_FILE', `PUSHDIVERT(5)F{LDAPRoute}$1 POPDIVERT`'dnl`'') +define(`LDAPROUTE_EQUIVALENT', `PUSHDIVERT(5)C{LDAPRouteEquiv}$1 +POPDIVERT`'dnl`'') +define(`LDAPROUTE_EQUIVALENT_FILE', `PUSHDIVERT(5)F{LDAPRouteEquiv}$1 +POPDIVERT`'dnl`'') define(`VIRTUSER_DOMAIN', `PUSHDIVERT(5)C{VirtHost}$1 define(`_VIRTHOSTS_') POPDIVERT`'dnl`'') @@ -192,7 +242,7 @@ define(`RELAY_DOMAIN', `PUSHDIVERT(5)C{R}$1 POPDIVERT`'dnl`'') define(`RELAY_DOMAIN_FILE', `PUSHDIVERT(5)F{R}$1 POPDIVERT`'dnl`'') -define(`TRUST_AUTH_MECH', `PUSHDIVERT(5)C{TrustAuthMech}$1 +define(`TRUST_AUTH_MECH', `_DEFIFNOT(`_USE_AUTH_',`1')PUSHDIVERT(5)C{TrustAuthMech}$1 POPDIVERT`'dnl`'') define(`_OPTINS', `ifdef(`$1', `$2$1$3')') @@ -212,15 +262,15 @@ define(`confFROM_LINE', `From $g $d') define(`confOPERATORS', `.:%@!^/[]+') define(`confSMTP_LOGIN_MSG', `$j Sendmail $v/$Z; $b') define(`_REC_AUTH_', `$.$?{auth_type}(authenticated') -define(`_REC_FULL_AUTH_', `$.$?{auth_type}(authenticated as ${auth_authen} $?{auth_author}for ${auth_author} $.with ${auth_type}') +define(`_REC_FULL_AUTH_', `$.$?{auth_type}(user=${auth_authen} $?{auth_author}author=${auth_author} $.mech=${auth_type}') define(`_REC_HDR_', `$?sfrom $s $.$?_($?s$|from $.$_)') define(`_REC_END_', `for $u; $|; $.$b$?g (envelope-from $g)$.') -define(`_REC_TLS_', `(using ${tls_version} with cipher ${cipher} (${cipher_bits} bits) verified ${verify})$.$?u') +define(`_REC_TLS_', `(version=${tls_version} cipher=${cipher} bits=${cipher_bits} verify=${verify})$.$?u') define(`_REC_BY_', `$.by $j ($v/$Z)$?r with $r$. id $i$?{tls_version}') define(`confRECEIVED_HEADER', `_REC_HDR_ - _REC_AUTH_$?{auth_ssf} (${auth_ssf} bits)$.) + _REC_AUTH_$?{auth_ssf} bits=${auth_ssf}$.) _REC_BY_ _REC_TLS_ _REC_END_') @@ -253,4 +303,4 @@ define(`confMILTER_MACROS_ENVRCPT', ``{rcpt_mailer}, {rcpt_host}, {rcpt_addr}'') divert(0)dnl -VERSIONID(`$Id: cfhead.m4,v 8.76.4.16 2001/03/06 22:56:36 ca Exp $') +VERSIONID(`$Id: cfhead.m4,v 8.107 2001/07/22 03:25:37 ca Exp $') diff --git a/contrib/sendmail/mail.local/mail.local.8 b/contrib/sendmail/mail.local/mail.local.8 index 2b23c31..2720578 100644 --- a/contrib/sendmail/mail.local/mail.local.8 +++ b/contrib/sendmail/mail.local/mail.local.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -8,20 +8,24 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: mail.local.8,v 8.14.14.5 2000/12/29 18:12:16 gshapiro Exp $ +.\" $Id: mail.local.8,v 8.23 2001/04/05 23:27:35 gshapiro Exp $ .\" .\" $FreeBSD$ .\" -.TH MAIL.LOCAL 8 "$Date: 2000/12/29 18:12:16 $" +.TH MAIL.LOCAL 8 "$Date: 2001/04/05 23:27:35 $" .SH NAME mail.local \- store mail in a mailbox .SH SYNOPSIS .B mail.local -.RB [ \-7 "] [" \-B "] [" \-b "] [" \-d "] [" \-l "] [" \-s "] [" \-f -.IR from "] " -.RB [ \-r -.IR from "] " "user ..." +.RB [ \-7 "] [" \-B "] [" \-b "] [" \-d "] [" \-D +.IR mbdb ] +.RB [ \-l "] [" \-s "] [" \-f +\fIfrom\fR|\fB\-r\fR +.IR from ] +.RB [ \-h +\fIfilename\fR ] +.I "user ..." .SH DESCRIPTION .B Mail.local reads the standard input up to an end-of-file and appends it to each @@ -47,6 +51,12 @@ if a mailbox exceeds quota. .TP .B \-d Specify this is a delivery (for backward compatibility). +This option has no effect. +.TP +.BI \-D " mbdb" +Specify the name of the mailbox database +which is used to look up local recipient names. +This option defaults to "pw", which means use getpwnam(). .TP .BI \-f " from" Specify the sender's name. @@ -63,6 +73,11 @@ status. .TP .BI \-r " from" Specify the sender's name (for backward compatibility). +Same as \-f. +.TP +.BI \-h " filename" +Store incoming mail in \fIfilename\fR in the user's home directory instead +of a system mail spool directory. .PP Individual mail messages in the mailbox are delimited by an empty line followed by a line beginning with the string ``From ''. @@ -100,10 +115,10 @@ Used to set the appropriate time zone on the timestamp. temporary files .TP /var/mail/user -user's mailbox directory +user's default mailbox directory .TP /var/mail/user.lock -lock file for a user's mailbox +lock file for a user's default mailbox .PD .SH SEE ALSO mail(1), diff --git a/contrib/sendmail/mail.local/mail.local.c b/contrib/sendmail/mail.local/mail.local.c index 5eca2e4..cd13f44 100644 --- a/contrib/sendmail/mail.local/mail.local.c +++ b/contrib/sendmail/mail.local/mail.local.c @@ -10,234 +10,113 @@ * */ -#ifndef lint -static char copyright[] = +#include <sm/gen.h> + +SM_IDSTR(copyright, "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1990, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* ! lint */ + The Regents of the University of California. All rights reserved.\n") + +SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.235 2001/12/30 04:59:39 gshapiro Exp $") -#ifndef lint -static char id[] = "@(#)$Id: mail.local.c,v 8.143.4.58 2001/06/01 05:33:31 gshapiro Exp $"; -#endif /* ! lint */ +#include <stdlib.h> +#include <sm/errstring.h> +#include <sm/io.h> +#include <sm/limits.h> +# include <unistd.h> +# ifdef EX_OK +# undef EX_OK /* unistd.h may have another use for this */ +# endif /* EX_OK */ +#include <sm/mbdb.h> +#include <sm/sysexits.h> /* $FreeBSD$ */ /* ** This is not intended to work on System V derived systems ** such as Solaris or HP-UX, since they use a totally different -** approach to mailboxes (essentially, they have a setgid program -** rather than setuid, and they rely on the ability to "give away" +** approach to mailboxes (essentially, they have a set-group-ID program +** rather than set-user-ID, and they rely on the ability to "give away" ** files to do their work). IT IS NOT A BUG that this doesn't ** work on such architectures. */ -/* additional mode for open() */ -# define EXTRA_MODE 0 - -# include <sys/types.h> -# include <sys/param.h> -# include <sys/stat.h> +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> +#include <stdlib.h> # include <sys/socket.h> # include <sys/file.h> - # include <netinet/in.h> # include <arpa/nameser.h> - -# include <fcntl.h> # include <netdb.h> -# include <pwd.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -# include <syslog.h> -# include <time.h> -# include <unistd.h> -# ifdef EX_OK -# undef EX_OK /* unistd.h may have another use for this */ -# endif /* EX_OK */ -# include <sysexits.h> -# include <ctype.h> +# include <pwd.h> -# ifndef __P -# include "sendmail/cdefs.h" -# endif /* ! __P */ -# include "sendmail/useful.h" - -extern size_t strlcpy __P((char *, const char *, size_t)); -extern size_t strlcat __P((char *, const char *, size_t)); - -# if defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__) || defined(IRIX64) || defined(IRIX5) || defined(IRIX6) -# ifndef HASSTRERROR -# define HASSTRERROR 1 -# endif /* ! HASSTRERROR */ -# endif /* defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__) || defined(IRIX64) || defined(IRIX5) || defined(IRIX6) */ - -# include "sendmail/errstring.h" - -# ifndef LOCKTO_RM -# define LOCKTO_RM 300 /* timeout for stale lockfile removal */ -# endif /* ! LOCKTO_RM */ -# ifndef LOCKTO_GLOB -# define LOCKTO_GLOB 400 /* global timeout for lockfile creation */ -# endif /* ! LOCKTO_GLOB */ - -# ifdef __STDC__ -# include <stdarg.h> -# define REALLOC(ptr, size) realloc(ptr, size) -# else /* __STDC__ */ -# include <varargs.h> -/* define a realloc() which works for NULL pointers */ -# define REALLOC(ptr, size) (((ptr) == NULL) ? malloc(size) : realloc(ptr, size)) -# endif /* __STDC__ */ - -# if (defined(sun) && defined(__svr4__)) || defined(__SVR4) -# define USE_LOCKF 1 -# define USE_SETEUID 1 -# define _PATH_MAILDIR "/var/mail" -# endif /* (defined(sun) && defined(__svr4__)) || defined(__SVR4) */ - -# ifdef NCR_MP_RAS3 -# define USE_LOCKF 1 -# define HASSNPRINTF 1 -# define _PATH_MAILDIR "/var/mail" -# endif /* NCR_MP_RAS3 */ - -# if defined(_AIX) -# define USE_LOCKF 1 -# define USE_SETEUID 1 -# endif /* defined(_AIX) */ - -# if defined(__hpux) -# define USE_LOCKF 1 -# define USE_SETRESUID 1 -# endif /* defined(__hpux) */ - -# ifdef DGUX -# define HASSNPRINTF 1 -# define USE_LOCKF 1 -# endif /* DGUX */ - -# if defined(_CRAY) -# if !defined(MAXPATHLEN) -# define MAXPATHLEN PATHSIZE -# endif /* !defined(MAXPATHLEN) */ -# define _PATH_MAILDIR "/usr/spool/mail" -# endif /* defined(_CRAY) */ - -# if defined(NeXT) && !defined(__APPLE__) -# include <libc.h> -# define _PATH_MAILDIR "/usr/spool/mail" -# define S_IRUSR S_IREAD -# define S_IWUSR S_IWRITE -# endif /* defined(NeXT) && !defined(__APPLE__) */ - -# if defined(IRIX64) || defined(IRIX5) || defined(IRIX6) -# include <paths.h> -# endif /* defined(IRIX64) || defined(IRIX5) || defined(IRIX6) */ +#include <sm/string.h> +#include <syslog.h> +#include <ctype.h> -/* - * If you don't have flock, you could try using lockf instead. - */ +#include <sm/conf.h> +#include <sendmail/pathnames.h> -# ifdef USE_LOCKF -# define flock(a, b) lockf(a, b, 0) -# ifdef LOCK_EX -# undef LOCK_EX -# endif /* LOCK_EX */ -# define LOCK_EX F_LOCK -# endif /* USE_LOCKF */ - -# ifndef LOCK_EX -# include <sys/file.h> -# endif /* ! LOCK_EX */ - -# if defined(BSD4_4) || defined(__GLIBC__) -# include <paths.h> -# define _PATH_LOCTMP "/var/tmp/local.XXXXXX" -# endif /* defined(BSD4_4) || defined(__GLIBC__) */ - -# ifdef BSD4_4 -# define HAS_ST_GEN 1 -# else /* BSD4_4 */ -# ifndef _BSD_VA_LIST_ -# define _BSD_VA_LIST_ va_list -# endif /* ! _BSD_VA_LIST_ */ -# endif /* BSD4_4 */ - -# if defined(BSD4_4) || defined(linux) -# define HASSNPRINTF 1 -# else /* defined(BSD4_4) || defined(linux) */ -# ifndef ultrix -extern FILE *fdopen __P((int, const char *)); -# endif /* ! ultrix */ -# endif /* defined(BSD4_4) || defined(linux) */ - -# if SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203) -# define CONTENTLENGTH 1 /* Needs the Content-Length header */ -# endif /* SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203) */ - -# if SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) -# define HASSNPRINTF 1 /* has snprintf starting in 2.6 */ -# endif /* SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) */ - -# ifdef HPUX11 -# define HASSNPRINTF 1 /* has snprintf starting in 11.X */ -# endif /* HPUX11 */ - -# if _AIX4 >= 40300 -# define HASSNPRINTF 1 /* has snprintf starting in 4.3 */ -# endif /* _AIX4 >= 40300 */ - -# if !HASSNPRINTF && !SFIO -extern int snprintf __P((char *, size_t, const char *, ...)); -# ifndef _CRAY -extern int vsnprintf __P((char *, size_t, const char *, ...)); -# endif /* ! _CRAY */ -# endif /* !HASSNPRINTF && !SFIO */ -/* -** If you don't have setreuid, and you have saved uids, and you have -** a seteuid() call that doesn't try to emulate using setuid(), then -** you can try defining USE_SETEUID. -*/ +/* additional mode for open() */ +# define EXTRA_MODE 0 + -# ifdef USE_SETEUID -# define setreuid(r, e) seteuid(e) -# endif /* USE_SETEUID */ +#ifndef LOCKTO_RM +# define LOCKTO_RM 300 /* timeout for stale lockfile removal */ +#endif /* ! LOCKTO_RM */ +#ifndef LOCKTO_GLOB +# define LOCKTO_GLOB 400 /* global timeout for lockfile creation */ +#endif /* ! LOCKTO_GLOB */ + +/* define a realloc() which works for NULL pointers */ +#define REALLOC(ptr, size) (((ptr) == NULL) ? malloc(size) : realloc(ptr, size)) /* -** And of course on hpux you have setresuid() +** If you don't have flock, you could try using lockf instead. */ -# ifdef USE_SETRESUID -# define setreuid(r, e) setresuid(-1, e, -1) -# endif /* USE_SETRESUID */ +#ifdef LDA_USE_LOCKF +# define flock(a, b) lockf(a, b, 0) +# ifdef LOCK_EX +# undef LOCK_EX +# endif /* LOCK_EX */ +# define LOCK_EX F_LOCK +#endif /* LDA_USE_LOCKF */ -# ifndef _PATH_LOCTMP -# define _PATH_LOCTMP "/var/tmp/local.XXXXXX" -# endif /* ! _PATH_LOCTMP */ -# ifndef _PATH_MAILDIR -# define _PATH_MAILDIR "/var/spool/mail" -# endif /* ! _PATH_MAILDIR */ +#ifndef LOCK_EX +# include <sys/file.h> +#endif /* ! LOCK_EX */ -# ifndef S_ISREG -# define S_ISREG(mode) (((mode) & _S_IFMT) == S_IFREG) -# endif /* ! S_ISREG */ +/* +** If you don't have setreuid, and you have saved uids, and you have +** a seteuid() call that doesn't try to emulate using setuid(), then +** you can try defining LDA_USE_SETEUID. +*/ -# ifdef MAILLOCK -# include <maillock.h> -# endif /* MAILLOCK */ +#ifdef LDA_USE_SETEUID +# define setreuid(r, e) seteuid(e) +#endif /* LDA_USE_SETEUID */ -# define U_UID pw->pw_uid -# define U_GID pw->pw_gid +#ifdef LDA_CONTENTLENGTH +# define CONTENTLENGTH 1 +#endif /* LDA_CONTENTLENGTH */ #ifndef INADDRSZ # define INADDRSZ 4 /* size of an IPv4 address in bytes */ #endif /* ! INADDRSZ */ +#ifdef MAILLOCK +# include <maillock.h> +#endif /* MAILLOCK */ + #ifndef MAILER_DAEMON # define MAILER_DAEMON "MAILER-DAEMON" #endif /* ! MAILER_DAEMON */ @@ -248,19 +127,20 @@ off_t HeaderLength; off_t BodyLength; #endif /* CONTENTLENGTH */ -bool EightBitMime = TRUE; /* advertise 8BITMIME in LMTP */ +bool EightBitMime = true; /* advertise 8BITMIME in LMTP */ char ErrBuf[10240]; /* error buffer */ int ExitVal = EX_OK; /* sysexits.h error value. */ -bool HoldErrs = FALSE; /* Hold errors in ErrBuf */ -bool LMTPMode = FALSE; -bool BounceQuota = FALSE; /* permanent error when over quota */ -bool nobiff = FALSE; -bool nofsync = FALSE; +bool nobiff = false; +bool nofsync = false; +bool HoldErrs = false; /* Hold errors in ErrBuf */ +bool LMTPMode = false; +bool BounceQuota = false; /* permanent error when over quota */ +char *HomeMailFile = NULL; /* store mail in homedir */ void deliver __P((int, char *)); int e_to_sys __P((int)); void notifybiff __P((char *)); -int store __P((char *, int, bool *)); +int store __P((char *, bool *)); void usage __P((void)); int lockmbox __P((char *)); void unlockmbox __P((void)); @@ -277,6 +157,8 @@ main(argc, argv) int ch, fd; uid_t uid; char *from; + char *mbdbname = "pw"; + int err; extern char *optarg; extern int optind; @@ -295,12 +177,12 @@ main(argc, argv) # endif /* LOG_MAIL */ from = NULL; - while ((ch = getopt(argc, argv, "7Bbdf:r:ls")) != -1) + while ((ch = getopt(argc, argv, "7BbdD:f:h:r:ls")) != -1) { switch(ch) { case '7': /* Do not advertise 8BITMIME */ - EightBitMime = FALSE; + EightBitMime = false; break; case 'B': @@ -308,12 +190,16 @@ main(argc, argv) break; case 'b': /* bounce mail when over quota. */ - BounceQuota = TRUE; + BounceQuota = true; break; case 'd': /* Backward compatible. */ break; + case 'D': /* mailbox database type */ + mbdbname = optarg; + break; + case 'f': case 'r': /* Backward compatible. */ if (from != NULL) @@ -324,8 +210,18 @@ main(argc, argv) from = optarg; break; + case 'h': + if (optarg != NULL || *optarg != '\0') + HomeMailFile = optarg; + else + { + mailerr(NULL, "-h: missing filename"); + usage(); + } + break; + case 'l': - LMTPMode = TRUE; + LMTPMode = true; break; case 's': @@ -344,6 +240,19 @@ main(argc, argv) if (!nobiff) notifybiff(NULL); + err = sm_mbdb_initialize(mbdbname); + if (err != EX_OK) + { + char *errcode = "521"; + + if (err == EX_TEMPFAIL) + errcode = "421"; + + mailerr(errcode, "Can not open mailbox database %s: %s", + mbdbname, sm_strexit(err)); + exit(err); + } + if (LMTPMode) { extern void dolmtp __P((void)); @@ -370,7 +279,6 @@ main(argc, argv) */ uid = getuid(); - if (from == NULL && ((from = getlogin()) == NULL || (pw = getpwnam(from)) == NULL || pw->pw_uid != uid)) @@ -386,9 +294,9 @@ main(argc, argv) ** at the expense of repeated failures and multiple deliveries. */ - HoldErrs = TRUE; - fd = store(from, 0, NULL); - HoldErrs = FALSE; + HoldErrs = true; + fd = store(from, NULL); + HoldErrs = false; if (fd < 0) { flush_error(); @@ -480,6 +388,8 @@ parseaddr(s, rcpt) s = MAILER_DAEMON; l = strlen(s) + 1; + if (l < 0) + return NULL; p = malloc(l); if (p == NULL) { @@ -487,7 +397,7 @@ parseaddr(s, rcpt) exit(EX_TEMPFAIL); } - (void) strlcpy(p, s, l); + (void) sm_strlcpy(p, s, l); return p; } @@ -495,9 +405,22 @@ char * process_recipient(addr) char *addr; { - if (getpwnam(addr) == NULL) + SM_MBDB_T user; + + switch (sm_mbdb_lookup(addr, &user)) + { + case EX_OK: + return NULL; + + case EX_NOUSER: return "550 5.1.1 User unknown"; - return NULL; + + case EX_TEMPFAIL: + return "451 4.3.0 User database failure; retry later"; + + default: + return "550 5.3.0 User database failure"; + } } #define RCPT_GROW 30 @@ -509,7 +432,7 @@ dolmtp() char **rcpt_addr = NULL; int rcpt_num = 0; int rcpt_alloc = 0; - bool gotlhlo = FALSE; + bool gotlhlo = false; char *err; int msgfd; char *p; @@ -520,7 +443,7 @@ dolmtp() memset(myhostname, '\0', sizeof myhostname); (void) gethostname(myhostname, sizeof myhostname - 1); if (myhostname[0] == '\0') - strlcpy(myhostname, "localhost", sizeof myhostname); + sm_strlcpy(myhostname, "localhost", sizeof myhostname); printf("220 %s LMTP ready\r\n", myhostname); for (;;) @@ -538,18 +461,18 @@ dolmtp() { case 'd': case 'D': - if (strcasecmp(buf, "data") == 0) + if (sm_strcasecmp(buf, "data") == 0) { - bool inbody = FALSE; + bool inbody = false; if (rcpt_num == 0) { mailerr("503 5.5.1", "No recipients"); continue; } - HoldErrs = TRUE; - msgfd = store(return_path, rcpt_num, &inbody); - HoldErrs = FALSE; + HoldErrs = true; + msgfd = store(return_path, &inbody); + HoldErrs = false; if (msgfd < 0 && !inbody) { flush_error(); @@ -579,7 +502,7 @@ dolmtp() case 'l': case 'L': - if (strncasecmp(buf, "lhlo ", 5) == 0) + if (sm_strncasecmp(buf, "lhlo ", 5) == 0) { /* check for duplicate per RFC 1651 4.2 */ if (gotlhlo) @@ -588,7 +511,7 @@ dolmtp() myhostname); continue; } - gotlhlo = TRUE; + gotlhlo = true; printf("250-%s\r\n", myhostname); if (EightBitMime) printf("250-8BITMIME\r\n"); @@ -602,7 +525,7 @@ dolmtp() case 'm': case 'M': - if (strncasecmp(buf, "mail ", 5) == 0) + if (sm_strncasecmp(buf, "mail ", 5) == 0) { if (return_path != NULL) { @@ -610,9 +533,9 @@ dolmtp() "Nested MAIL command"); continue; } - if (strncasecmp(buf+5, "from:", 5) != 0 || + if (sm_strncasecmp(buf+5, "from:", 5) != 0 || ((return_path = parseaddr(buf + 10, - FALSE)) == NULL)) + false)) == NULL)) { mailerr("501 5.5.4", "Syntax error in parameters"); @@ -627,7 +550,7 @@ dolmtp() case 'n': case 'N': - if (strcasecmp(buf, "noop") == 0) + if (sm_strcasecmp(buf, "noop") == 0) { printf("250 2.0.0 Ok\r\n"); continue; @@ -638,7 +561,7 @@ dolmtp() case 'q': case 'Q': - if (strcasecmp(buf, "quit") == 0) + if (sm_strcasecmp(buf, "quit") == 0) { printf("221 2.0.0 Bye\r\n"); exit(EX_OK); @@ -649,7 +572,7 @@ dolmtp() case 'r': case 'R': - if (strncasecmp(buf, "rcpt ", 5) == 0) + if (sm_strncasecmp(buf, "rcpt ", 5) == 0) { if (return_path == NULL) { @@ -671,9 +594,9 @@ dolmtp() exit(EX_TEMPFAIL); } } - if (strncasecmp(buf + 5, "to:", 3) != 0 || + if (sm_strncasecmp(buf + 5, "to:", 3) != 0 || ((rcpt_addr[rcpt_num] = parseaddr(buf + 8, - TRUE)) == NULL)) + true)) == NULL)) { mailerr("501 5.5.4", "Syntax error in parameters"); @@ -689,7 +612,7 @@ dolmtp() printf("250 2.1.5 Ok\r\n"); continue; } - else if (strcasecmp(buf, "rset") == 0) + else if (sm_strcasecmp(buf, "rset") == 0) { printf("250 2.0.0 Ok\r\n"); @@ -707,7 +630,7 @@ rset: case 'v': case 'V': - if (strncasecmp(buf, "vrfy ", 5) == 0) + if (sm_strncasecmp(buf, "vrfy ", 5) == 0) { printf("252 2.3.3 Try RCPT to attempt delivery\r\n"); continue; @@ -727,25 +650,24 @@ rset: } int -store(from, lmtprcpts, inbody) +store(from, inbody) char *from; - int lmtprcpts; bool *inbody; { FILE *fp = NULL; time_t tval; - bool eline; - bool fullline = TRUE; /* current line is terminated */ + bool eline; /* previous line was empty */ + bool fullline = true; /* current line is terminated */ bool prevfl; /* previous line was terminated */ char line[2048]; int fd; char tmpbuf[sizeof _PATH_LOCTMP + 1]; if (inbody != NULL) - *inbody = FALSE; + *inbody = false; (void) umask(0077); - (void) strlcpy(tmpbuf, _PATH_LOCTMP, sizeof tmpbuf); + (void) sm_strlcpy(tmpbuf, _PATH_LOCTMP, sizeof tmpbuf); if ((fd = mkstemp(tmpbuf)) < 0 || (fp = fdopen(fd, "w+")) == NULL) { mailerr("451 4.3.0", "Unable to open temporary file"); @@ -759,7 +681,7 @@ store(from, lmtprcpts, inbody) (void) fflush(stdout); } if (inbody != NULL) - *inbody = TRUE; + *inbody = true; (void) time(&tval); (void) fprintf(fp, "From %s %s", from, ctime(&tval)); @@ -770,7 +692,7 @@ store(from, lmtprcpts, inbody) #endif /* CONTENTLENGTH */ line[0] = '\0'; - eline = TRUE; + eline = true; while (fgets(line, sizeof(line), stdin) != (char *) NULL) { size_t line_len = 0; @@ -792,7 +714,7 @@ store(from, lmtprcpts, inbody) } /* Check to see if we have the full line from fgets() */ - fullline = FALSE; + fullline = false; if (line_len > 0) { if (line[line_len - 1] == '\n') @@ -804,7 +726,7 @@ store(from, lmtprcpts, inbody) line[line_len - 1] = '\0'; line_len--; } - fullline = TRUE; + fullline = true; } else if (line[line_len - 1] == '\r') { @@ -813,19 +735,19 @@ store(from, lmtprcpts, inbody) if (peek == '\n') { line[line_len - 1] = '\n'; - fullline = TRUE; + fullline = true; } else (void) ungetc(peek, stdin); } } else - fullline = TRUE; + fullline = true; #ifdef CONTENTLENGTH if (prevfl && line[0] == '\n' && HeaderLength == 0) { - eline = FALSE; + eline = false; if (fp != NULL) HeaderLength = ftell(fp); if (HeaderLength <= 0) @@ -840,7 +762,7 @@ store(from, lmtprcpts, inbody) } #else /* CONTENTLENGTH */ if (prevfl && line[0] == '\n') - eline = TRUE; + eline = true; #endif /* CONTENTLENGTH */ else { @@ -848,12 +770,12 @@ store(from, lmtprcpts, inbody) fp != NULL && !memcmp(line, "From ", 5)) (void) putc('>', fp); - eline = FALSE; + eline = false; #ifdef CONTENTLENGTH /* discard existing "Content-Length:" headers */ if (prevfl && HeaderLength == 0 && (line[0] == 'C' || line[0] == 'c') && - strncasecmp(line, ContentHdr, 15) == 0) + sm_strncasecmp(line, ContentHdr, 15) == 0) { /* ** be paranoid: clear the line @@ -908,15 +830,10 @@ store(from, lmtprcpts, inbody) if (HeaderLength > 0 && BodyLength >= 0) { - extern char *quad_to_string(); - - if (sizeof BodyLength > sizeof(long)) - snprintf(line, sizeof line, "%s\n", - quad_to_string(BodyLength)); - else - snprintf(line, sizeof line, "%ld\n", - (long) BodyLength); - strlcpy(&ContentHdr[16], line, sizeof(ContentHdr) - 16); + (void) sm_snprintf(line, sizeof line, "%lld\n", + (LONGLONG_T) BodyLength); + (void) sm_strlcpy(&ContentHdr[16], line, + sizeof(ContentHdr) - 16); } else BodyLength = -1; /* Something is wrong here */ @@ -943,9 +860,9 @@ deliver(fd, name) { struct stat fsb; struct stat sb; - struct passwd *pw; char path[MAXPATHLEN]; int mbfd = -1, nr = 0, nw, off; + int exitval; char *p; char *errcode; off_t curoff; @@ -954,26 +871,42 @@ deliver(fd, name) int readamount; #endif /* CONTENTLENGTH */ char biffmsg[100], buf[8*1024]; - extern char *quad_to_string(); - + SM_MBDB_T user; /* ** Disallow delivery to unknown names -- special mailboxes can be ** handled in the sendmail aliases file. */ - if ((pw = getpwnam(name)) == NULL) + exitval = sm_mbdb_lookup(name, &user); + switch (exitval) { - if (ExitVal == EX_TEMPFAIL) - errcode = "451 4.3.0"; - else - { - ExitVal = EX_UNAVAILABLE; - errcode = "550 5.1.1"; - } - mailerr(errcode, "Unknown name: %s", name); + case EX_OK: + break; + + case EX_NOUSER: + exitval = EX_UNAVAILABLE; + mailerr("550 5.1.1", "%s: User unknown", name); + break; + + case EX_TEMPFAIL: + mailerr("451 4.3.0", "%s: User database failure; retry later", + name); + break; + + default: + exitval = EX_UNAVAILABLE; + mailerr("550 5.3.0", "%s: User database failure", name); + break; + } + + if (exitval != EX_OK) + { + if (ExitVal != EX_TEMPFAIL) + ExitVal = exitval; return; } + endpwent(); /* @@ -995,7 +928,29 @@ deliver(fd, name) } - (void) snprintf(path, sizeof(path), "%s/%s", _PATH_MAILDIR, name); + if (HomeMailFile == NULL) + { + if (sm_snprintf(path, sizeof(path), "%s/%s", + _PATH_MAILDIR, name) >= sizeof(path)) + { + exitval = EX_UNAVAILABLE; + mailerr("550 5.1.1", "%s: Invalid mailbox path", name); + return; + } + } + else if (*user.mbdb_homedir == '\0') + { + exitval = EX_UNAVAILABLE; + mailerr("550 5.1.1", "%s: User missing home directory", name); + return; + } + else if (sm_snprintf(path, sizeof(path), "%s/%s", + user.mbdb_homedir, HomeMailFile) >= sizeof(path)) + { + exitval = EX_UNAVAILABLE; + mailerr("550 5.1.1", "%s: Invalid mailbox path", name); + return; + } /* @@ -1037,7 +992,7 @@ tryagain: errcode = "551 5.3.0"; mailerr(errcode, "lockmailbox %s failed; error code %d %s", - p, off, errno > 0 ? errstring(errno) : ""); + p, off, errno > 0 ? sm_errstring(errno) : ""); return; } @@ -1045,7 +1000,7 @@ tryagain: { int save_errno; int mode = S_IRUSR|S_IWUSR; - gid_t gid = U_GID; + gid_t gid = user.mbdb_gid; #ifdef MAILGID (void) umask(0007); @@ -1071,13 +1026,13 @@ tryagain: /* open failed, don't try again */ mailerr("450 4.2.0", "%s: %s", path, - errstring(save_errno)); + sm_errstring(save_errno)); goto err0; } - else if (fchown(mbfd, U_UID, gid) < 0) + else if (fchown(mbfd, user.mbdb_uid, gid) < 0) { mailerr("451 4.3.0", "chown %u.%u: %s", - U_UID, gid, name); + user.mbdb_uid, gid, name); goto err1; } else @@ -1089,7 +1044,7 @@ tryagain: ** is no longer valid; better safe than sorry. */ - sb.st_uid = U_UID; + sb.st_uid = user.mbdb_uid; (void) close(mbfd); mbfd = -1; } @@ -1099,28 +1054,29 @@ tryagain: mailerr("550 5.2.0", "%s: irregular file", path); goto err0; } - else if (sb.st_uid != U_UID) + else if (sb.st_uid != user.mbdb_uid) { ExitVal = EX_CANTCREAT; mailerr("550 5.2.0", "%s: wrong ownership (%d)", - path, sb.st_uid); + path, (int) sb.st_uid); goto err0; } /* change UID for quota checks */ - if (setreuid(0, U_UID) < 0) + if (setreuid(0, user.mbdb_uid) < 0) { mailerr("450 4.2.0", "setreuid(0, %d): %s (r=%d, e=%d)", - U_UID, errstring(errno), getuid(), geteuid()); + (int) user.mbdb_uid, sm_errstring(errno), + (int) getuid(), (int) geteuid()); goto err1; } #ifdef DEBUG - fprintf(stderr, "new euid = %d\n", geteuid()); + fprintf(stderr, "new euid = %d\n", (int) geteuid()); #endif /* DEBUG */ mbfd = open(path, O_APPEND|O_WRONLY|EXTRA_MODE, 0); if (mbfd < 0) { - mailerr("450 4.2.0", "%s: %s", path, errstring(errno)); + mailerr("450 4.2.0", "%s: %s", path, sm_errstring(errno)); goto err0; } else if (fstat(mbfd, &fsb) < 0 || @@ -1140,11 +1096,48 @@ tryagain: goto err1; } +#if 0 + /* + ** This code could be reused if we decide to add a + ** per-user quota field to the sm_mbdb interface. + */ + + /* + ** Fail if the user has a quota specified, and delivery of this + ** message would exceed that quota. We bounce such failures using + ** EX_UNAVAILABLE, unless there were internal problems, since + ** storing immense messages for later retries can cause queueing + ** issues. + */ + + if (ui.quota > 0) + { + struct stat dsb; + + if (fstat(fd, &dsb) < 0) + { + ExitVal = EX_TEMPFAIL; + mailerr("451 4.3.0", + "%s: fstat: can't stat temporary storage: %s", + ui.mailspool, sm_errstring(errno)); + goto err1; + } + + if (dsb.st_size + sb.st_size + 1 > ui.quota) + { + ExitVal = EX_UNAVAILABLE; + mailerr("551 5.2.2", + "%s: Mailbox full or quota exceeded", + ui.mailspool); + goto err1; + } + } +#endif /* 0 */ /* Wait until we can get a lock on the file. */ if (flock(mbfd, LOCK_EX) < 0) { - mailerr("450 4.2.0", "%s: %s", path, errstring(errno)); + mailerr("450 4.2.0", "%s: %s", path, sm_errstring(errno)); goto err1; } @@ -1152,23 +1145,19 @@ tryagain: { /* Get the starting offset of the new message for biff. */ curoff = lseek(mbfd, (off_t) 0, SEEK_END); - if (sizeof curoff > sizeof(long)) - (void) snprintf(biffmsg, sizeof(biffmsg), "%s@%s\n", - name, quad_to_string(curoff)); - else - (void) snprintf(biffmsg, sizeof(biffmsg), "%s@%ld\n", - name, (long) curoff); + (void) sm_snprintf(biffmsg, sizeof(biffmsg), "%s@%lld\n", + name, (LONGLONG_T) curoff); } /* Copy the message into the file. */ if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) -1) { mailerr("450 4.2.0", "Temporary file: %s", - errstring(errno)); + sm_errstring(errno)); goto err1; } #ifdef DEBUG - fprintf(stderr, "before writing: euid = %d\n", geteuid()); + fprintf(stderr, "before writing: euid = %d\n", (int) geteuid()); #endif /* DEBUG */ #ifdef CONTENTLENGTH headerbytes = (BodyLength >= 0) ? HeaderLength : -1 ; @@ -1176,7 +1165,7 @@ tryagain: { if (headerbytes == 0) { - snprintf(buf, sizeof buf, "%s", ContentHdr); + (void) sm_snprintf(buf, sizeof buf, "%s", ContentHdr); nr = strlen(buf); headerbytes = -1; readamount = 0; @@ -1206,7 +1195,7 @@ tryagain: errcode = "552 5.2.2"; #endif /* EDQUOT */ mailerr(errcode, "%s: %s", - path, errstring(errno)); + path, sm_errstring(errno)); goto err3; } } @@ -1214,18 +1203,18 @@ tryagain: if (nr < 0) { mailerr("450 4.2.0", "Temporary file: %s", - errstring(errno)); + sm_errstring(errno)); goto err3; } /* Flush to disk, don't wait for update. */ if (!nofsync && fsync(mbfd) < 0) { - mailerr("450 4.2.0", "%s: %s", path, errstring(errno)); + mailerr("450 4.2.0", "%s: %s", path, sm_errstring(errno)); err3: (void) setreuid(0, 0); #ifdef DEBUG - fprintf(stderr, "reset euid = %d\n", geteuid()); + fprintf(stderr, "reset euid = %d\n", (int) geteuid()); #endif /* DEBUG */ (void) ftruncate(mbfd, curoff); err1: if (mbfd >= 0) @@ -1242,7 +1231,7 @@ err0: unlockmbox(); if (errno == EDQUOT && BounceQuota) errcode = "552 5.2.2"; #endif /* EDQUOT */ - mailerr(errcode, "%s: %s", path, errstring(errno)); + mailerr(errcode, "%s: %s", path, sm_errstring(errno)); (void) truncate(path, curoff); } else if (!nobiff) @@ -1251,11 +1240,11 @@ err0: unlockmbox(); if (setreuid(0, 0) < 0) { mailerr("450 4.2.0", "setreuid(0, 0): %s", - errstring(errno)); + sm_errstring(errno)); goto err0; } #ifdef DEBUG - fprintf(stderr, "reset euid = %d\n", geteuid()); + fprintf(stderr, "reset euid = %d\n", (int) geteuid()); #endif /* DEBUG */ unlockmbox(); if (LMTPMode) @@ -1269,7 +1258,7 @@ err0: unlockmbox(); ** EPA 11/94. */ -bool Locked = FALSE; +bool Locked = false; #ifdef MAILLOCK int @@ -1282,7 +1271,7 @@ lockmbox(name) return 0; if ((r = maillock(name, 15)) == L_SUCCESS) { - Locked = TRUE; + Locked = true; return 0; } switch (r) @@ -1309,7 +1298,7 @@ unlockmbox() { if (Locked) mailunlock(); - Locked = FALSE; + Locked = false; } #else /* MAILLOCK */ @@ -1326,7 +1315,7 @@ lockmbox(path) return 0; if (strlen(path) + 6 > sizeof LockName) return EX_SOFTWARE; - (void) snprintf(LockName, sizeof LockName, "%s.lock", path); + (void) sm_snprintf(LockName, sizeof LockName, "%s.lock", path); (void) time(&start); for (; ; sleep(5)) { @@ -1346,7 +1335,7 @@ lockmbox(path) { /* defeat lock checking programs which test pid */ (void) write(fd, "0", 2); - Locked = TRUE; + Locked = true; (void) close(fd); return 0; } @@ -1376,7 +1365,7 @@ unlockmbox() if (!Locked) return; (void) unlink(LockName); - Locked = FALSE; + Locked = false; } #endif /* MAILLOCK */ @@ -1384,7 +1373,7 @@ void notifybiff(msg) char *msg; { - static bool initialized = FALSE; + static bool initialized = false; static int f = -1; struct hostent *hp; struct servent *sp; @@ -1393,7 +1382,7 @@ notifybiff(msg) if (!initialized) { - initialized = TRUE; + initialized = true; /* Be silent if biff service not available. */ if ((sp = getservbyname("biff", "udp")) == NULL || @@ -1424,11 +1413,12 @@ void usage() { ExitVal = EX_USAGE; - mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-l] [-f from] [-s] user ..."); + mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-d] [-l] [-s] [-f from|-r from] [-h filename] user ..."); exit(ExitVal); } void +/*VARARGS2*/ #ifdef __STDC__ mailerr(const char *hdr, const char *fmt, ...) #else /* __STDC__ */ @@ -1439,25 +1429,19 @@ mailerr(hdr, fmt, va_alist) #endif /* __STDC__ */ { size_t len = 0; - va_list ap; + SM_VA_LOCAL_DECL (void) e_to_sys(errno); -#ifdef __STDC__ - va_start(ap, fmt); -#else /* __STDC__ */ - va_start(ap); -#endif /* __STDC__ */ + SM_VA_START(ap, fmt); - if (LMTPMode) + if (LMTPMode && hdr != NULL) { - if (hdr != NULL) - { - snprintf(ErrBuf, sizeof ErrBuf, "%s ", hdr); - len = strlen(ErrBuf); - } + sm_snprintf(ErrBuf, sizeof ErrBuf, "%s ", hdr); + len = strlen(ErrBuf); } - (void) vsnprintf(&ErrBuf[len], sizeof ErrBuf - len, fmt, ap); + (void) sm_vsnprintf(&ErrBuf[len], sizeof ErrBuf - len, fmt, ap); + SM_VA_END(ap); if (!HoldErrs) flush_error(); @@ -1646,7 +1630,7 @@ _gettemp(path, doopen) extern int errno; register char *start, *trv; struct stat sbuf; - u_int pid; + unsigned int pid; pid = getpid(); for (trv = path; *trv; ++trv); /* extra X's get set to 0's */ diff --git a/contrib/sendmail/mailstats/mailstats.c b/contrib/sendmail/mailstats/mailstats.c index 20a539b..f3f9cb7 100644 --- a/contrib/sendmail/mailstats/mailstats.c +++ b/contrib/sendmail/mailstats/mailstats.c @@ -12,17 +12,15 @@ * */ -#ifndef lint -static char copyright[] = +#include <sm/gen.h> + +SM_IDSTR(copyright, "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1988, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* ! lint */ + The Regents of the University of California. All rights reserved.\n") -#ifndef lint -static char id[] = "@(#)$Id: mailstats.c,v 8.53.16.13 2001/05/07 22:06:38 gshapiro Exp $"; -#endif /* ! lint */ +SM_IDSTR(id, "@(#)$Id: mailstats.c,v 8.95 2001/12/30 04:59:40 gshapiro Exp $") /* $FreeBSD$ */ @@ -37,6 +35,8 @@ static char id[] = "@(#)$Id: mailstats.c,v 8.53.16.13 2001/05/07 22:06:38 gshapi #endif /* EX_OK */ #include <sysexits.h> +#include <sm/errstring.h> +#include <sm/limits.h> #include <sendmail/sendmail.h> #include <sendmail/mailstats.h> #include <sendmail/pathnames.h> @@ -44,7 +44,6 @@ static char id[] = "@(#)$Id: mailstats.c,v 8.53.16.13 2001/05/07 22:06:38 gshapi #define MNAMELEN 20 /* max length of mailer name */ - int main(argc, argv) int argc; @@ -56,11 +55,15 @@ main(argc, argv) int ch, fd; char *sfile; char *cfile; - FILE *cfp; + SM_FILE_T *cfp; bool mnames; bool progmode; + bool trunc; long frmsgs = 0, frbytes = 0, tomsgs = 0, tobytes = 0, rejmsgs = 0; long dismsgs = 0; +#if _FFR_QUARANTINE + long quarmsgs = 0; +#endif /* _FFR_QUARANTINE */ time_t now; char mtable[MAXMAILERS][MNAMELEN + 1]; char sfilebuf[MAXLINE]; @@ -70,15 +73,19 @@ main(argc, argv) extern char *optarg; extern int optind; - - cfile = _PATH_SENDMAILCF; + cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL); sfile = NULL; - mnames = TRUE; - progmode = FALSE; - while ((ch = getopt(argc, argv, "C:f:op")) != -1) + mnames = true; + progmode = false; + trunc = false; + while ((ch = getopt(argc, argv, "cC:f:opP")) != -1) { switch (ch) { + case 'c': + cfile = getcfname(0, 0, SM_GET_SUBMIT_CF, NULL); + break; + case 'C': cfile = optarg; break; @@ -88,18 +95,22 @@ main(argc, argv) break; case 'o': - mnames = FALSE; + mnames = false; break; case 'p': - progmode = TRUE; + trunc = true; + /* FALLTHROUGH */ + + case 'P': + progmode = true; break; case '?': default: usage: - (void) fputs("usage: mailstats [-C cffile] [-f stfile] [-o] [-p]\n", - stderr); + (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, + "usage: mailstats [-C cffile] [-P] [-f stfile] [-o] [-p]\n"); exit(EX_USAGE); } } @@ -109,21 +120,22 @@ main(argc, argv) if (argc != 0) goto usage; - if ((cfp = fopen(cfile, "r")) == NULL) + if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY, + NULL)) == NULL) { save_errno = errno; - fprintf(stderr, "mailstats: "); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "mailstats: "); errno = save_errno; - perror(cfile); + sm_perror(cfile); exit(EX_NOINPUT); } mno = 0; - (void) strlcpy(mtable[mno++], "prog", MNAMELEN + 1); - (void) strlcpy(mtable[mno++], "*file*", MNAMELEN + 1); - (void) strlcpy(mtable[mno++], "*include*", MNAMELEN + 1); + (void) sm_strlcpy(mtable[mno++], "prog", MNAMELEN + 1); + (void) sm_strlcpy(mtable[mno++], "*file*", MNAMELEN + 1); + (void) sm_strlcpy(mtable[mno++], "*include*", MNAMELEN + 1); - while (fgets(buf, sizeof(buf), cfp) != NULL) + while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL) { register char *b; char *s; @@ -136,7 +148,7 @@ main(argc, argv) break; case 'O': /* option -- see if .st file */ - if (strncasecmp(b, " StatusFile", 11) == 0 && + if (sm_strncasecmp(b, " StatusFile", 11) == 0 && !(isascii(b[11]) && isalnum(b[11]))) { /* new form -- find value */ @@ -153,12 +165,12 @@ main(argc, argv) } /* this is the S or StatusFile option -- save it */ - if (strlcpy(sfilebuf, b, sizeof sfilebuf) >= + if (sm_strlcpy(sfilebuf, b, sizeof sfilebuf) >= sizeof sfilebuf) { - fprintf(stderr, - "StatusFile filename too long: %.30s...\n", - b); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "StatusFile filename too long: %.30s...\n", + b); exit(EX_CONFIG); } b = strchr(sfilebuf, '#'); @@ -178,9 +190,9 @@ main(argc, argv) if (mno >= MAXMAILERS) { - fprintf(stderr, - "Too many mailers defined, %d max.\n", - MAXMAILERS); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "Too many mailers defined, %d max.\n", + MAXMAILERS); exit(EX_SOFTWARE); } m = mtable[mno]; @@ -197,13 +209,14 @@ main(argc, argv) if (i == mno) mno++; } - (void) fclose(cfp); + (void) sm_io_close(cfp, SM_TIME_DEFAULT); for (; mno < MAXMAILERS; mno++) - mtable[mno][0]='\0'; + mtable[mno][0] = '\0'; if (sfile == NULL) { - fprintf(stderr, "mailstats: no statistics file located\n"); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "mailstats: no statistics file located\n"); exit (EX_OSFILE); } @@ -211,9 +224,9 @@ main(argc, argv) if ((fd < 0) || (i = read(fd, &stats, sizeof stats)) < 0) { save_errno = errno; - (void) fputs("mailstats: ", stderr); + (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, "mailstats: "); errno = save_errno; - perror(sfile); + sm_perror(sfile); exit(EX_NOINPUT); } if (i == 0) @@ -222,9 +235,10 @@ main(argc, argv) if ((i = read(fd, &stats, sizeof stats)) < 0) { save_errno = errno; - (void) fputs("mailstats: ", stderr); + (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, + "mailstats: "); errno = save_errno; - perror(sfile); + sm_perror(sfile); exit(EX_NOINPUT); } else if (i == 0) @@ -237,21 +251,24 @@ main(argc, argv) { if (stats.stat_magic != STAT_MAGIC) { - fprintf(stderr, - "mailstats: incorrect magic number in %s\n", - sfile); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "mailstats: incorrect magic number in %s\n", + sfile); exit(EX_OSERR); } else if (stats.stat_version != STAT_VERSION) { - fprintf(stderr, - "mailstats version (%d) incompatible with %s version (%d)\n", - STAT_VERSION, sfile, stats.stat_version); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "mailstats version (%d) incompatible with %s version (%d)\n", + STAT_VERSION, sfile, + stats.stat_version); + exit(EX_OSERR); } else if (i != sizeof stats || stats.stat_size != sizeof(stats)) { - (void) fputs("mailstats: file size changed.\n", stderr); + (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, + "mailstats: file size changed.\n"); exit(EX_OSERR); } } @@ -259,17 +276,28 @@ main(argc, argv) if (progmode) { (void) time(&now); - printf("%ld %ld\n", (long) stats.stat_itime, (long) now); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%ld %ld\n", + (long) stats.stat_itime, (long) now); } else { - printf("Statistics from %s", ctime(&stats.stat_itime)); - printf(" M msgsfr bytes_from msgsto bytes_to msgsrej msgsdis%s\n", - mnames ? " Mailer" : ""); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Statistics from %s", + ctime(&stats.stat_itime)); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " M msgsfr bytes_from msgsto bytes_to msgsrej msgsdis"); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " msgsqur"); +#endif /* _FFR_QUARANTINE */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s\n", + mnames ? " Mailer" : ""); } for (i = 0; i < MAXMAILERS; i++) { if (stats.stat_nf[i] || stats.stat_nt[i] || +#if _FFR_QUARANTINE + stats.stat_nq[i] || +#endif /* _FFR_QUARANTINE */ stats.stat_nr[i] || stats.stat_nd[i]) { char *format; @@ -278,39 +306,78 @@ main(argc, argv) format = "%2d %8ld %10ld %8ld %10ld %6ld %6ld"; else format = "%2d %8ld %10ldK %8ld %10ldK %6ld %6ld"; - printf(format, i, - stats.stat_nf[i], stats.stat_bf[i], - stats.stat_nt[i], stats.stat_bt[i], - stats.stat_nr[i], stats.stat_nd[i]); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + format, i, + stats.stat_nf[i], + stats.stat_bf[i], + stats.stat_nt[i], + stats.stat_bt[i], + stats.stat_nr[i], + stats.stat_nd[i]); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " %6ld", stats.stat_nq[i]); +#endif /* _FFR_QUARANTINE */ if (mnames) - printf(" %s", mtable[i]); - printf("\n"); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " %s", + mtable[i]); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n"); frmsgs += stats.stat_nf[i]; frbytes += stats.stat_bf[i]; tomsgs += stats.stat_nt[i]; tobytes += stats.stat_bt[i]; rejmsgs += stats.stat_nr[i]; dismsgs += stats.stat_nd[i]; +#if _FFR_QUARANTINE + quarmsgs += stats.stat_nq[i]; +#endif /* _FFR_QUARANTINE */ } } if (progmode) { - printf(" T %8ld %10ld %8ld %10ld %6ld %6ld\n", - frmsgs, frbytes, tomsgs, tobytes, rejmsgs, dismsgs); - printf(" C %8ld %8ld %6ld\n", - stats.stat_cf, stats.stat_ct, stats.stat_cr); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " T %8ld %10ld %8ld %10ld %6ld %6ld", + frmsgs, frbytes, tomsgs, tobytes, rejmsgs, + dismsgs); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " %6ld", quarmsgs); +#endif /* _FFR_QUARANTINE */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n"); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " C %8ld %8ld %6ld\n", + stats.stat_cf, stats.stat_ct, + stats.stat_cr); (void) close(fd); - fd = open(sfile, O_RDWR | O_TRUNC); - if (fd >= 0) - (void) close(fd); + if (trunc) + { + fd = open(sfile, O_RDWR | O_TRUNC); + if (fd >= 0) + (void) close(fd); + } } else { - printf("=============================================================\n"); - printf(" T %8ld %10ldK %8ld %10ldK %6ld %6ld\n", - frmsgs, frbytes, tomsgs, tobytes, rejmsgs, dismsgs); - printf(" C %8ld %10s %8ld %10s %6ld\n", - stats.stat_cf, "", stats.stat_ct, "", stats.stat_cr); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "============================================================="); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "========"); +#endif /* _FFR_QUARANTINE */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n"); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " T %8ld %10ldK %8ld %10ldK %6ld %6ld", + frmsgs, frbytes, tomsgs, tobytes, rejmsgs, + dismsgs); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " %6ld", quarmsgs); +#endif /* _FFR_QUARANTINE */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n"); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " C %8ld %10s %8ld %10s %6ld\n", + stats.stat_cf, "", stats.stat_ct, "", + stats.stat_cr); } exit(EX_OK); /* NOTREACHED */ diff --git a/contrib/sendmail/makemap/makemap.c b/contrib/sendmail/makemap/makemap.c index b3d7b0e..29dd47f 100644 --- a/contrib/sendmail/makemap/makemap.c +++ b/contrib/sendmail/makemap/makemap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1992 Eric P. Allman. All rights reserved. * Copyright (c) 1992, 1993 @@ -11,18 +11,16 @@ * */ -#ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.\n\ +#include <sm/gen.h> + +SM_IDSTR(copyright, +"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1992 Eric P. Allman. All rights reserved.\n\ Copyright (c) 1992, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* ! lint */ + The Regents of the University of California. All rights reserved.\n") -#ifndef lint -static char id[] = "@(#)$Id: makemap.c,v 8.135.4.13 2000/10/05 23:00:50 gshapiro Exp $"; -#endif /* ! lint */ +SM_IDSTR(id, "@(#)$Id: makemap.c,v 8.175 2001/12/28 22:44:01 ca Exp $") /* $FreeBSD$ */ @@ -48,31 +46,24 @@ uid_t RunAsUid; uid_t RunAsGid; char *RunAsUserName; int Verbose = 2; -bool DontInitGroups = FALSE; +bool DontInitGroups = false; uid_t TrustedUid = 0; BITMAP256 DontBlameSendmail; #define BUFSIZE 1024 -#if _FFR_DELIM -# define ISSEP(c) ((sep == '\0' && isascii(c) && isspace(c)) || (c) == sep) -#else /* _FFR_DELIM */ -# define ISSEP(c) (isascii(c) && isspace(c)) -#endif /* _FFR_DELIM */ - +#define ISSEP(c) (sep == '\0' ? isascii(c) && isspace(c) : (c) == sep) static void usage(progname) char *progname; { - fprintf(stderr, - "Usage: %s [-C cffile] [-N] [-c cachesize] [-d] [-e] [-f] [-l] [-o] [-r] [-s] %s[-u] [-v] type mapname\n", - progname, -#if _FFR_DELIM - "[-t delimiter] " -#else /* _FFR_DELIM */ - "" -#endif /* _FFR_DELIM */ - ); + /* XXX break the usage output into multiple lines? it's too long */ + sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "Usage: %s [-C cffile] [-N] [-c cachesize] [-d] [-e] [-f] [-l] [-o] [-r] [-s] [-t delimiter] [-u] [-v] type mapname\n", + progname); +#if _FFR_COMMENT_CHAR + /* add -D comment-char */ +#endif /* _FFR_COMMENT_CHAR */ exit(EX_USAGE); } @@ -83,21 +74,20 @@ main(argc, argv) { char *progname; char *cfile; - bool inclnull = FALSE; - bool notrunc = FALSE; - bool allowreplace = FALSE; - bool allowempty = FALSE; - bool verbose = FALSE; - bool foldcase = TRUE; - bool unmake = FALSE; -#if _FFR_DELIM + bool inclnull = false; + bool notrunc = false; + bool allowreplace = false; + bool allowempty = false; + bool verbose = false; + bool foldcase = true; + bool unmake = false; char sep = '\0'; -#endif /* _FFR_DELIM */ + char comment = '#'; int exitstat; int opt; char *typename = NULL; char *mapname = NULL; - int lineno; + unsigned int lineno; int st; int mode; int smode; @@ -111,7 +101,7 @@ main(argc, argv) SMDB_USER_INFO user_info; char ibuf[BUFSIZE]; #if HASFCHOWN - FILE *cfp; + SM_FILE_T *cfp; char buf[MAXLINE]; #endif /* HASFCHOWN */ static char rnamebuf[MAXNAME]; /* holds RealUserName */ @@ -126,25 +116,24 @@ main(argc, argv) progname++; else progname = argv[0]; - cfile = _PATH_SENDMAILCF; + cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL); clrbitmap(DontBlameSendmail); RunAsUid = RealUid = getuid(); RunAsGid = RealGid = getgid(); pw = getpwuid(RealUid); if (pw != NULL) - (void) strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf); + (void) sm_strlcpy(rnamebuf, pw->pw_name, sizeof rnamebuf); else - (void) snprintf(rnamebuf, sizeof rnamebuf, "Unknown UID %d", - (int) RealUid); + (void) sm_snprintf(rnamebuf, sizeof rnamebuf, + "Unknown UID %d", (int) RealUid); RunAsUserName = RealUserName = rnamebuf; user_info.smdbu_id = RunAsUid; user_info.smdbu_group_id = RunAsGid; - (void) strlcpy(user_info.smdbu_name, RunAsUserName, + (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName, SMDB_MAX_USER_NAME_LEN); - -#define OPTIONS "C:Nc:t:deflorsuv" +#define OPTIONS "C:D:Nc:deflorst:uv" while ((opt = getopt(argc, argv, OPTIONS)) != -1) { switch (opt) @@ -154,7 +143,7 @@ main(argc, argv) break; case 'N': - inclnull = TRUE; + inclnull = true; break; case 'c': @@ -162,28 +151,34 @@ main(argc, argv) break; case 'd': - params.smdbp_allow_dup = TRUE; + params.smdbp_allow_dup = true; break; case 'e': - allowempty = TRUE; + allowempty = true; break; case 'f': - foldcase = FALSE; + foldcase = false; break; +#if _FFR_COMMENT_CHAR + case 'D': + comment = *optarg; + break; +#endif /* _FFR_COMMENT_CHAR */ + case 'l': smdb_print_available_types(); exit(EX_OK); break; case 'o': - notrunc = TRUE; + notrunc = true; break; case 'r': - allowreplace = TRUE; + allowreplace = true; break; case 's': @@ -193,23 +188,22 @@ main(argc, argv) setbitn(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail); break; -#if _FFR_DELIM case 't': if (optarg == NULL || *optarg == '\0') { - fprintf(stderr, "Invalid separator\n"); + sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "Invalid separator\n"); break; } sep = *optarg; break; -#endif /* _FFR_DELIM */ case 'u': - unmake = TRUE; + unmake = true; break; case 'v': - verbose = TRUE; + verbose = true; break; default: @@ -240,12 +234,14 @@ main(argc, argv) #if HASFCHOWN /* Find TrustedUser value in sendmail.cf */ - if ((cfp = fopen(cfile, "r")) == NULL) + if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY, + NULL)) == NULL) { - fprintf(stderr, "makemap: %s: %s", cfile, errstring(errno)); + sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "makemap: %s: %s", + cfile, sm_errstring(errno)); exit(EX_NOINPUT); } - while (fgets(buf, sizeof(buf), cfp) != NULL) + while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL) { register char *b; @@ -271,8 +267,9 @@ main(argc, argv) TrustedUid = 0; pw = getpwnam(b); if (pw == NULL) - fprintf(stderr, - "TrustedUser: unknown user %s\n", b); + (void) sm_io_fprintf(smioerr, + SM_TIME_DEFAULT, + "TrustedUser: unknown user %s\n", b); else TrustedUid = pw->pw_uid; } @@ -280,8 +277,9 @@ main(argc, argv) # ifdef UID_MAX if (TrustedUid > UID_MAX) { - fprintf(stderr, - "TrustedUser: uid value (%ld) > UID_MAX (%ld)", + (void) sm_io_fprintf(smioerr, + SM_TIME_DEFAULT, + "TrustedUser: uid value (%ld) > UID_MAX (%ld)", (long) TrustedUid, (long) UID_MAX); TrustedUid = 0; @@ -295,7 +293,7 @@ main(argc, argv) continue; } } - (void) fclose(cfp); + (void) sm_io_close(cfp, SM_TIME_DEFAULT); #endif /* HASFCHOWN */ if (!params.smdbp_allow_dup && !allowreplace) @@ -327,13 +325,14 @@ main(argc, argv) if (errno == SMDBE_UNSUPPORTED_DB_TYPE && (hint = smdb_db_definition(typename)) != NULL) - fprintf(stderr, - "%s: Need to recompile with -D%s for %s support\n", - progname, hint, typename); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: Need to recompile with -D%s for %s support\n", + progname, hint, typename); else - fprintf(stderr, - "%s: error opening type %s map %s: %s\n", - progname, typename, mapname, errstring(errno)); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: error opening type %s map %s: %s\n", + progname, typename, mapname, + sm_errstring(errno)); exit(EX_CANTCREAT); } @@ -344,9 +343,9 @@ main(argc, argv) errno = database->smdb_set_owner(database, TrustedUid, -1); if (errno != SMDBE_OK) { - fprintf(stderr, - "WARNING: ownership change on %s failed %s", - mapname, errstring(errno)); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "WARNING: ownership change on %s failed %s", + mapname, sm_errstring(errno)); } } @@ -361,9 +360,9 @@ main(argc, argv) if (errno != SMDBE_OK) { - fprintf(stderr, - "%s: cannot make cursor for type %s map %s\n", - progname, typename, mapname); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: cannot make cursor for type %s map %s\n", + progname, typename, mapname); exit(EX_SOFTWARE); } @@ -377,11 +376,12 @@ main(argc, argv) if (errno != SMDBE_OK) break; - printf("%.*s\t%.*s\n", - (int) db_key.size, - (char *) db_key.data, - (int) db_val.size, - (char *)db_val.data); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "%.*s\t%.*s\n", + (int) db_key.size, + (char *) db_key.data, + (int) db_val.size, + (char *)db_val.data); } (void) cursor->smdbc_close(cursor); @@ -389,7 +389,8 @@ main(argc, argv) else { lineno = 0; - while (fgets(ibuf, sizeof ibuf, stdin) != NULL) + while (sm_io_fgets(smioin, SM_TIME_DEFAULT, ibuf, sizeof ibuf) + != NULL) { register char *p; @@ -402,26 +403,23 @@ main(argc, argv) p = strchr(ibuf, '\n'); if (p != NULL) *p = '\0'; - else if (!feof(stdin)) + else if (!sm_io_eof(smioin)) { - fprintf(stderr, - "%s: %s: line %d: line too long (%ld bytes max)\n", - progname, mapname, lineno, (long) sizeof ibuf); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: %s: line %u: line too long (%ld bytes max)\n", + progname, mapname, lineno, + (long) sizeof ibuf); exitstat = EX_DATAERR; continue; } - if (ibuf[0] == '\0' || ibuf[0] == '#') + if (ibuf[0] == '\0' || ibuf[0] == comment) continue; - if ( -#if _FFR_DELIM - sep == '\0' && -#endif /* _FFR_DELIM */ - isascii(ibuf[0]) && isspace(ibuf[0])) + if (sep == '\0' && isascii(ibuf[0]) && isspace(ibuf[0])) { - fprintf(stderr, - "%s: %s: line %d: syntax error (leading space)\n", - progname, mapname, lineno); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: %s: line %u: syntax error (leading space)\n", + progname, mapname, lineno); exitstat = EX_DATAERR; continue; } @@ -441,14 +439,14 @@ main(argc, argv) if (*p != '\0') *p++ = '\0'; - while (ISSEP(*p)) + while (*p != '\0' && ISSEP(*p)) p++; if (!allowempty && *p == '\0') { - fprintf(stderr, - "%s: %s: line %d: no RHS for LHS %s\n", - progname, mapname, lineno, - (char *) db_key.data); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: %s: line %u: no RHS for LHS %s\n", + progname, mapname, lineno, + (char *) db_key.data); exitstat = EX_DATAERR; continue; } @@ -464,9 +462,10 @@ main(argc, argv) if (verbose) { - printf("key=`%s', val=`%s'\n", - (char *) db_key.data, - (char *) db_val.data); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "key=`%s', val=`%s'\n", + (char *) db_key.data, + (char *) db_val.data); } errno = database->smdb_put(database, &db_key, &db_val, @@ -488,19 +487,20 @@ main(argc, argv) if (st < 0) { - fprintf(stderr, - "%s: %s: line %d: key %s: put error: %s\n", - progname, mapname, lineno, - (char *) db_key.data, - errstring(errno)); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: %s: line %u: key %s: put error: %s\n", + progname, mapname, lineno, + (char *) db_key.data, + sm_errstring(errno)); exitstat = EX_IOERR; } else if (st > 0) { - fprintf(stderr, - "%s: %s: line %d: key %s: duplicate key\n", - progname, mapname, - lineno, (char *) db_key.data); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: %s: line %u: key %s: duplicate key\n", + progname, mapname, + lineno, + (char *) db_key.data); exitstat = EX_DATAERR; } } @@ -513,61 +513,15 @@ main(argc, argv) errno = database->smdb_close(database); if (errno != SMDBE_OK) { - fprintf(stderr, "%s: close(%s): %s\n", - progname, mapname, errstring(errno)); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: close(%s): %s\n", + progname, mapname, sm_errstring(errno)); exitstat = EX_IOERR; } smdb_free_database(database); exit(exitstat); + /* NOTREACHED */ return exitstat; } - -/*VARARGS1*/ -void -#ifdef __STDC__ -message(const char *msg, ...) -#else /* __STDC__ */ -message(msg, va_alist) - const char *msg; - va_dcl -#endif /* __STDC__ */ -{ - const char *m; - VA_LOCAL_DECL - - m = msg; - if (isascii(m[0]) && isdigit(m[0]) && - isascii(m[1]) && isdigit(m[1]) && - isascii(m[2]) && isdigit(m[2]) && m[3] == ' ') - m += 4; - VA_START(msg); - (void) vfprintf(stderr, m, ap); - VA_END; - (void) fprintf(stderr, "\n"); -} - -/*VARARGS1*/ -void -#ifdef __STDC__ -syserr(const char *msg, ...) -#else /* __STDC__ */ -syserr(msg, va_alist) - const char *msg; - va_dcl -#endif /* __STDC__ */ -{ - const char *m; - VA_LOCAL_DECL - - m = msg; - if (isascii(m[0]) && isdigit(m[0]) && - isascii(m[1]) && isdigit(m[1]) && - isascii(m[2]) && isdigit(m[2]) && m[3] == ' ') - m += 4; - VA_START(msg); - (void) vfprintf(stderr, m, ap); - VA_END; - (void) fprintf(stderr, "\n"); -} diff --git a/contrib/sendmail/praliases/praliases.c b/contrib/sendmail/praliases/praliases.c index 47ac4e5..ab71ce0 100644 --- a/contrib/sendmail/praliases/praliases.c +++ b/contrib/sendmail/praliases/praliases.c @@ -11,18 +11,16 @@ * */ -#ifndef lint -static char copyright[] = +#include <sm/gen.h> + +SM_IDSTR(copyright, "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1983 Eric P. Allman. All rights reserved.\n\ Copyright (c) 1988, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* ! lint */ + The Regents of the University of California. All rights reserved.\n") -#ifndef lint -static char id[] = "@(#)$Id: praliases.c,v 8.59.4.19 2001/02/28 02:37:57 ca Exp $"; -#endif /* ! lint */ +SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.93 2001/09/11 04:05:07 gshapiro Exp $") /* $FreeBSD$ */ @@ -52,12 +50,10 @@ uid_t RunAsUid; uid_t RunAsGid; char *RunAsUserName; int Verbose = 2; -bool DontInitGroups = FALSE; +bool DontInitGroups = false; uid_t TrustedUid = 0; BITMAP256 DontBlameSendmail; -extern void syserr __P((const char *, ...)); - # define DELIMITERS " ,/" # define PATH_SEPARATOR ':' @@ -68,7 +64,7 @@ main(argc, argv) { char *cfile; char *filename = NULL; - FILE *cfp; + SM_FILE_T *cfp; int ch; char afilebuf[MAXLINE]; char buf[MAXLINE]; @@ -77,7 +73,6 @@ main(argc, argv) extern char *optarg; extern int optind; - clrbitmap(DontBlameSendmail); RunAsUid = RealUid = getuid(); RunAsGid = RealGid = getgid(); @@ -86,14 +81,14 @@ main(argc, argv) { if (strlen(pw->pw_name) > MAXNAME - 1) pw->pw_name[MAXNAME] = 0; - snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name); + sm_snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name); } else - (void) snprintf(rnamebuf, sizeof rnamebuf, "Unknown UID %d", - (int) RealUid); + (void) sm_snprintf(rnamebuf, sizeof rnamebuf, + "Unknown UID %d", (int) RealUid); RunAsUserName = RealUserName = rnamebuf; - cfile = _PATH_SENDMAILCF; + cfile = getcfname(0, 0, SM_GET_SENDMAIL_CF, NULL); while ((ch = getopt(argc, argv, "C:f:")) != -1) { switch ((char)ch) { @@ -105,8 +100,8 @@ main(argc, argv) break; case '?': default: - (void)fprintf(stderr, - "usage: praliases [-C cffile] [-f aliasfile]\n"); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "usage: praliases [-C cffile] [-f aliasfile]\n"); exit(EX_USAGE); } } @@ -119,14 +114,16 @@ main(argc, argv) exit(EX_OK); } - if ((cfp = fopen(cfile, "r")) == NULL) + if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY, + NULL)) == NULL) { - fprintf(stderr, "praliases: %s: %s\n", - cfile, errstring(errno)); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "praliases: %s: %s\n", cfile, + sm_errstring(errno)); exit(EX_NOINPUT); } - while (fgets(buf, sizeof(buf), cfp) != NULL) + while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) != NULL) { register char *b, *p; @@ -138,7 +135,7 @@ main(argc, argv) switch (*b++) { case 'O': /* option -- see if alias file */ - if (strncasecmp(b, " AliasFile", 10) == 0 && + if (sm_strncasecmp(b, " AliasFile", 10) == 0 && !(isascii(b[10]) && isalnum(b[10]))) { /* new form -- find value */ @@ -155,13 +152,13 @@ main(argc, argv) } /* this is the A or AliasFile option -- save it */ - if (strlcpy(afilebuf, b, sizeof afilebuf) >= + if (sm_strlcpy(afilebuf, b, sizeof afilebuf) >= sizeof afilebuf) { - fprintf(stderr, - "praliases: AliasFile filename too long: %.30s\n", + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "praliases: AliasFile filename too long: %.30s\n", b); - (void) fclose(cfp); + (void) sm_io_close(cfp, SM_TIME_DEFAULT); exit(EX_CONFIG); } b = afilebuf; @@ -179,7 +176,7 @@ main(argc, argv) /* find end of spec */ if (p != NULL) { - bool quoted = FALSE; + bool quoted = false; for (; *p != '\0'; p++) { @@ -226,7 +223,7 @@ main(argc, argv) continue; } } - (void) fclose(cfp); + (void) sm_io_close(cfp, SM_TIME_DEFAULT); exit(EX_OK); /* NOTREACHED */ return EX_OK; @@ -282,8 +279,8 @@ praliases(filename, argc, argv) strcmp(db_type, "btree") != 0 && strcmp(db_type, "dbm") != 0) { - fprintf(stderr, - "praliases: Skipping non-file based alias type %s\n", + sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "praliases: Skipping non-file based alias type %s\n", db_type); return; } @@ -293,8 +290,8 @@ praliases(filename, argc, argv) { if (colon != NULL) *colon = ':'; - fprintf(stderr, "praliases: illegal alias specification: %s\n", - filename); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "praliases: illegal alias specification: %s\n", filename); goto fatal; } @@ -303,14 +300,16 @@ praliases(filename, argc, argv) user_info.smdbu_id = RunAsUid; user_info.smdbu_group_id = RunAsGid; - strlcpy(user_info.smdbu_name, RunAsUserName, SMDB_MAX_USER_NAME_LEN); + (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName, + SMDB_MAX_USER_NAME_LEN); result = smdb_open_database(&database, db_name, O_RDONLY, 0, SFF_ROOTOK, db_type, &user_info, ¶ms); if (result != SMDBE_OK) { - fprintf(stderr, "praliases: %s: open: %s\n", - db_name, errstring(result)); + sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "praliases: %s: open: %s\n", + db_name, sm_errstring(result)); goto fatal; } @@ -322,8 +321,9 @@ praliases(filename, argc, argv) result = database->smdb_cursor(database, &cursor, 0); if (result != SMDBE_OK) { - fprintf(stderr, "praliases: %s: set cursor: %s\n", - db_name, errstring(result)); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "praliases: %s: set cursor: %s\n", db_name, + sm_errstring(result)); goto fatal; } @@ -342,18 +342,19 @@ praliases(filename, argc, argv) continue; #endif /* 0 */ - printf("%.*s:%.*s\n", - (int) db_key.size, - (char *) db_key.data, - (int) db_value.size, - (char *) db_value.data); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "%.*s:%.*s\n", + (int) db_key.size, + (char *) db_key.data, + (int) db_value.size, + (char *) db_value.data); } if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY) { - fprintf(stderr, + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "praliases: %s: get value at cursor: %s\n", - db_name, errstring(result)); + db_name, sm_errstring(result)); goto fatal; } } @@ -374,14 +375,17 @@ praliases(filename, argc, argv) } if (get_res == SMDBE_OK) { - printf("%.*s:%.*s\n", - (int) db_key.size, - (char *) db_key.data, - (int) db_value.size, - (char *) db_value.data); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "%.*s:%.*s\n", + (int) db_key.size, + (char *) db_key.data, + (int) db_value.size, + (char *) db_value.data); } else - printf("%s: No such key\n", (char *) db_key.data); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "%s: No such key\n", + (char *)db_key.data); } fatal: @@ -393,51 +397,3 @@ praliases(filename, argc, argv) *colon = ':'; return; } - -/*VARARGS1*/ -void -#ifdef __STDC__ -message(const char *msg, ...) -#else /* __STDC__ */ -message(msg, va_alist) - const char *msg; - va_dcl -#endif /* __STDC__ */ -{ - const char *m; - VA_LOCAL_DECL - - m = msg; - if (isascii(m[0]) && isdigit(m[0]) && - isascii(m[1]) && isdigit(m[1]) && - isascii(m[2]) && isdigit(m[2]) && m[3] == ' ') - m += 4; - VA_START(msg); - (void) vfprintf(stderr, m, ap); - VA_END; - (void) fprintf(stderr, "\n"); -} - -/*VARARGS1*/ -void -#ifdef __STDC__ -syserr(const char *msg, ...) -#else /* __STDC__ */ -syserr(msg, va_alist) - const char *msg; - va_dcl -#endif /* __STDC__ */ -{ - const char *m; - VA_LOCAL_DECL - - m = msg; - if (isascii(m[0]) && isdigit(m[0]) && - isascii(m[1]) && isdigit(m[1]) && - isascii(m[2]) && isdigit(m[2]) && m[3] == ' ') - m += 4; - VA_START(msg); - (void) vfprintf(stderr, m, ap); - VA_END; - (void) fprintf(stderr, "\n"); -} diff --git a/contrib/sendmail/rmail/rmail.c b/contrib/sendmail/rmail/rmail.c index 40c5aac..3177fd2 100644 --- a/contrib/sendmail/rmail/rmail.c +++ b/contrib/sendmail/rmail/rmail.c @@ -10,17 +10,15 @@ * */ -#ifndef lint -static char copyright[] = +#include <sm/gen.h> + +SM_IDSTR(copyright, "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1988, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* ! lint */ + The Regents of the University of California. All rights reserved.\n") -#ifndef lint -static char id[] = "@(#)$Id: rmail.c,v 8.39.4.12 2001/05/07 22:06:39 gshapiro Exp $"; -#endif /* ! lint */ +SM_IDSTR(id, "@(#)$Id: rmail.c,v 8.61 2001/09/18 21:45:29 gshapiro Exp $") /* $FreeBSD$ */ @@ -56,69 +54,18 @@ static char id[] = "@(#)$Id: rmail.c,v 8.39.4.12 2001/05/07 22:06:39 gshapiro Ex #include <ctype.h> #include <fcntl.h> -#ifdef BSD4_4 -# define FORK vfork -# include <paths.h> -#else /* BSD4_4 */ -# define FORK fork -# ifndef _PATH_SENDMAIL -# define _PATH_SENDMAIL "/usr/lib/sendmail" -# endif /* ! _PATH_SENDMAIL */ -#endif /* BSD4_4 */ -#include <stdio.h> +#include <sm/io.h> #include <stdlib.h> -#include <string.h> +#include <sm/string.h> #include <unistd.h> #ifdef EX_OK # undef EX_OK /* unistd.h may have another use for this */ #endif /* EX_OK */ #include <sysexits.h> -#ifndef MAX -# define MAX(a, b) ((a) < (b) ? (b) : (a)) -#endif /* ! MAX */ - -#ifndef __P -# ifdef __STDC__ -# define __P(protos) protos -# else /* __STDC__ */ -# define __P(protos) () -# define const -# endif /* __STDC__ */ -#endif /* ! __P */ - -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif /* ! STDIN_FILENO */ - -#if defined(BSD4_4) || defined(linux) || SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) || _AIX4 >= 40300 || defined(HPUX11) -# define HASSNPRINTF 1 -#endif /* defined(BSD4_4) || defined(linux) || SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) || _AIX4 >= 40300 || defined(HPUX11) */ - -#if defined(sun) && !defined(BSD) && !defined(SOLARIS) && !defined(__svr4__) && !defined(__SVR4) -# define memmove(d, s, l) (bcopy((s), (d), (l))) -#endif /* defined(sun) && !defined(BSD) && !defined(SOLARIS) && !defined(__svr4__) && !defined(__SVR4) */ - -#if !HASSNPRINTF && !SFIO -extern int snprintf __P((char *, size_t, const char *, ...)); -#endif /* !HASSNPRINTF && !SFIO */ - -#if defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__) || defined(IRIX64) || defined(IRIX5) || defined(IRIX6) -# ifndef HASSTRERROR -# define HASSTRERROR 1 -# endif /* ! HASSTRERROR */ -#endif /* defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__) || - defined(IRIX64) || defined(IRIX5) || defined(IRIX6) */ - -#if defined(SUNOS403) || defined(NeXT) || (defined(MACH) && defined(i386) && !defined(__GNU__)) || defined(oldBSD43) || defined(MORE_BSD) || defined(umipsbsd) || defined(ALTOS_SYSTEM_V) || defined(RISCOS) || defined(_AUX_SOURCE) || defined(UMAXV) || defined(titan) || defined(UNIXWARE) || defined(sony_news) || defined(luna) || defined(nec_ews_svr4) || defined(_nec_ews_svr4) || defined(__MAXION__) -# undef WIFEXITED -# undef WEXITSTATUS -# define WIFEXITED(st) (((st) & 0377) == 0) -# define WEXITSTATUS(st) (((st) >> 8) & 0377) -#endif /* defined(SUNOS403) || defined(NeXT) || (defined(MACH) && defined(i386) && !defined(__GNU__)) || defined(oldBSD43) || defined(MORE_BSD) || defined(umipsbsd) || defined(ALTOS_SYSTEM_V) || defined(RISCOS) || defined(_AUX_SOURCE) || defined(UMAXV) || defined(titan) || defined(UNIXWARE) || defined(sony_news) || defined(luna) || defined(nec_ews_svr4) || defined(_nec_ews_svr4) || defined(__MAXION__) */ - - -#include "sendmail/errstring.h" +#include <sm/conf.h> +#include <sm/errstring.h> +#include <sendmail/pathnames.h> static void err __P((int, const char *, ...)); static void usage __P((void)); @@ -136,7 +83,7 @@ xalloc(sz) if (sz <= 0) sz = 1; - p = malloc((unsigned) sz); + p = malloc(sz); if (p == NULL) err(EX_TEMPFAIL, "out of memory"); return (p); @@ -150,7 +97,7 @@ main(argc, argv) int ch, debug, i, pdes[2], pid, status; size_t fplen = 0, fptlen = 0, len; off_t offset; - FILE *fp; + SM_FILE_T *fp; char *addrp = NULL, *domain, *p, *t; char *from_path, *from_sys, *from_user; char **args, buf[2048], lbuf[2048]; @@ -188,8 +135,9 @@ main(argc, argv) for (offset = 0; ; ) { /* Get and nul-terminate the line. */ - if (fgets(lbuf, sizeof(lbuf), stdin) == NULL) - exit(EX_DATAERR); + if (sm_io_fgets(smioin, SM_TIME_DEFAULT, lbuf, + sizeof(lbuf)) == NULL) + err(EX_DATAERR, "no data"); if ((p = strchr(lbuf, '\n')) == NULL) err(EX_DATAERR, "line too long"); *p = '\0'; @@ -223,7 +171,10 @@ main(argc, argv) } *t = '\0'; if (debug) - fprintf(stderr, "remote from: %s\n", p); + (void) sm_io_fprintf(smioerr, + SM_TIME_DEFAULT, + "remote from: %s\n", + p); break; } } @@ -243,7 +194,9 @@ main(argc, argv) err(EX_DATAERR, "corrupted From line: %s", lbuf); if (debug) - fprintf(stderr, "bang: %s\n", p); + (void) sm_io_fprintf(smioerr, + SM_TIME_DEFAULT, + "bang: %s\n", p); } } @@ -263,8 +216,10 @@ main(argc, argv) { from_sys = newstr(p); if (debug) - fprintf(stderr, "from_sys: %s\n", - from_sys); + (void) sm_io_fprintf(smioerr, + SM_TIME_DEFAULT, + "from_sys: %s\n", + from_sys); } /* Concatenate to the path string. */ @@ -273,14 +228,14 @@ main(argc, argv) { fplen = 0; if ((from_path = malloc(fptlen = 256)) == NULL) - err(EX_TEMPFAIL, NULL); + err(EX_TEMPFAIL, "out of memory"); } if (fplen + len + 2 > fptlen) { - fptlen += MAX(fplen + len + 2, 256); + fptlen += SM_MAX(fplen + len + 2, 256); if ((from_path = realloc(from_path, fptlen)) == NULL) - err(EX_TEMPFAIL, NULL); + err(EX_TEMPFAIL, "out of memory"); } memmove(from_path + fplen, p, len); fplen += len; @@ -304,20 +259,24 @@ main(argc, argv) if (debug) { if (from_path != NULL) - fprintf(stderr, "from_path: %s\n", from_path); - fprintf(stderr, "from_user: %s\n", from_user); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "from_path: %s\n", + from_path); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "from_user: %s\n", from_user); } if (offset != -1) - offset = (off_t)ftell(stdin); + offset = (off_t)sm_io_tell(smioin, SM_TIME_DEFAULT); } - /* Allocate args (with room for sendmail args as well as recipients) */ + /* Allocate args (with room for sendmail args as well as recipients */ args = (char **)xalloc(sizeof(*args) * (10 + argc)); i = 0; args[i++] = _PATH_SENDMAIL; /* Build sendmail's argument list. */ + args[i++] = "-G"; /* relay submission */ args[i++] = "-oee"; /* No errors, just status. */ #ifdef QUEUE_ONLY args[i++] = "-odq"; /* Queue it, don't try to deliver. */ @@ -328,16 +287,16 @@ main(argc, argv) /* set from system and protocol used */ if (from_sys == NULL) - snprintf(buf, sizeof(buf), "-p%s", domain); + sm_snprintf(buf, sizeof(buf), "-p%s", domain); else if (strchr(from_sys, '.') == NULL) - snprintf(buf, sizeof(buf), "-p%s:%s.%s", + sm_snprintf(buf, sizeof(buf), "-p%s:%s.%s", domain, from_sys, domain); else - snprintf(buf, sizeof(buf), "-p%s:%s", domain, from_sys); + sm_snprintf(buf, sizeof(buf), "-p%s:%s", domain, from_sys); args[i++] = newstr(buf); /* Set name of ``from'' person. */ - snprintf(buf, sizeof(buf), "-f%s%s", + sm_snprintf(buf, sizeof(buf), "-f%s%s", from_path ? from_path : "", from_user); args[i++] = newstr(buf); @@ -360,7 +319,7 @@ main(argc, argv) len = strlen(*argv) + 3; if ((args[i] = malloc(len)) == NULL) err(EX_TEMPFAIL, "Cannot malloc"); - snprintf(args[i++], len, "<%s>", *argv); + sm_snprintf(args[i++], len, "<%s>", *argv); } argv++; argc--; @@ -373,9 +332,11 @@ main(argc, argv) if (debug) { - fprintf(stderr, "Sendmail arguments:\n"); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "Sendmail arguments:\n"); for (i = 0; args[i] != NULL; i++) - fprintf(stderr, "\t%s\n", args[i]); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "\t%s\n", args[i]); } /* @@ -394,12 +355,12 @@ main(argc, argv) } if (pipe(pdes) < 0) - err(EX_OSERR, NULL); + err(EX_OSERR, "pipe failed"); - switch (pid = FORK()) + switch (pid = fork()) { case -1: /* Err. */ - err(EX_OSERR, NULL); + err(EX_OSERR, "fork failed"); /* NOTREACHED */ case 0: /* Child. */ @@ -410,25 +371,27 @@ main(argc, argv) } (void) close(pdes[1]); (void) execv(_PATH_SENDMAIL, args); - _exit(127); + err(EX_UNAVAILABLE, "%s", _PATH_SENDMAIL); /* NOTREACHED */ } - if ((fp = fdopen(pdes[1], "w")) == NULL) - err(EX_OSERR, NULL); + if ((fp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &(pdes[1]), + SM_IO_WRONLY, NULL)) == NULL) + err(EX_OSERR, "sm_io_open failed"); (void) close(pdes[0]); /* Copy the file down the pipe. */ do { - (void) fprintf(fp, "%s", lbuf); - } while (fgets(lbuf, sizeof(lbuf), stdin) != NULL); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s", lbuf); + } while (sm_io_fgets(smioin, SM_TIME_DEFAULT, lbuf, + sizeof(lbuf)) != NULL); - if (ferror(stdin)) - err(EX_TEMPFAIL, "stdin: %s", errstring(errno)); + if (sm_io_error(smioin)) + err(EX_TEMPFAIL, "stdin: %s", sm_errstring(errno)); - if (fclose(fp)) - err(EX_OSERR, NULL); + if (sm_io_close(fp, SM_TIME_DEFAULT)) + err(EX_OSERR, "sm_io_close failed"); if ((waitpid(pid, &status, 0)) == -1) err(EX_OSERR, "%s", _PATH_SENDMAIL); @@ -447,16 +410,11 @@ main(argc, argv) static void usage() { - (void) fprintf(stderr, "usage: rmail [-T] [-D domain] user ...\n"); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "usage: rmail [-T] [-D domain] user ...\n"); exit(EX_USAGE); } -#ifdef __STDC__ -# include <stdarg.h> -#else /* __STDC__ */ -# include <varargs.h> -#endif /* __STDC__ */ - static void #ifdef __STDC__ err(int eval, const char *fmt, ...) @@ -467,15 +425,15 @@ err(eval, fmt, va_alist) va_dcl #endif /* __STDC__ */ { - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else /* __STDC__ */ - va_start(ap); -#endif /* __STDC__ */ - (void) fprintf(stderr, "rmail: "); - (void) vfprintf(stderr, fmt, ap); - va_end(ap); - (void) fprintf(stderr, "\n"); + SM_VA_LOCAL_DECL + + if (fmt != NULL) + { + SM_VA_START(ap, fmt); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "rmail: "); + (void) sm_io_vfprintf(smioerr, SM_TIME_DEFAULT, fmt, ap); + SM_VA_END(ap); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "\n"); + } exit(eval); } diff --git a/contrib/sendmail/smrsh/smrsh.8 b/contrib/sendmail/smrsh/smrsh.8 index 3c8fffb..ba3f300 100644 --- a/contrib/sendmail/smrsh/smrsh.8 +++ b/contrib/sendmail/smrsh/smrsh.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" Copyright (c) 1993 Eric P. Allman. All rights reserved. .\" Copyright (c) 1993 @@ -9,11 +9,11 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: smrsh.8,v 8.11.16.2 2000/12/15 19:50:46 gshapiro Exp $ +.\" $Id: smrsh.8,v 8.15 2001/01/24 00:40:47 gshapiro Exp $ .\" .\" $FreeBSD$ .\" -.TH SMRSH 8 "$Date: 2000/12/15 19:50:46 $" +.TH SMRSH 8 "$Date: 2001/01/24 00:40:47 $" .SH NAME smrsh \- restricted shell for sendmail .SH SYNOPSIS @@ -77,10 +77,10 @@ in the sm.bin directory (using the ``#!'' syntax); it simply disallows execution of arbitrary programs. .SH COMPILATION Compilation should be trivial on most systems. -You may need to use \-DPATH=\e"\fIpath\fP\e" +You may need to use \-DSMRSH_PATH=\e"\fIpath\fP\e" to adjust the default search path (defaults to ``/bin:/usr/bin'') -and/or \-DCMDBIN=\e"\fIdir\fP\e" +and/or \-DSMRSH_CMDBIN=\e"\fIdir\fP\e" to change the default program directory (defaults to ``/usr/libexec/sm.bin''). .SH FILES diff --git a/contrib/sendmail/smrsh/smrsh.c b/contrib/sendmail/smrsh/smrsh.c index c95deea..d0613a1 100644 --- a/contrib/sendmail/smrsh/smrsh.c +++ b/contrib/sendmail/smrsh/smrsh.c @@ -11,18 +11,16 @@ * */ -#ifndef lint -static char copyright[] = +#include <sm/gen.h> + +SM_IDSTR(copyright, "@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1993 Eric P. Allman. All rights reserved.\n\ Copyright (c) 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* ! lint */ + The Regents of the University of California. All rights reserved.\n") -#ifndef lint -static char id[] = "@(#)$Id: smrsh.c,v 8.31.4.9 2001/04/24 04:11:51 ca Exp $"; -#endif /* ! lint */ +SM_IDSTR(id, "@(#)$Id: smrsh.c,v 8.55 2001/09/11 04:05:22 gshapiro Exp $") /* $FreeBSD$ */ @@ -57,7 +55,8 @@ static char id[] = "@(#)$Id: smrsh.c,v 8.31.4.9 2001/04/24 04:11:51 ca Exp $"; */ #include <unistd.h> -#include <stdio.h> +#include <sm/io.h> +#include <sm/string.h> #include <sys/file.h> #include <string.h> #include <ctype.h> @@ -69,18 +68,16 @@ static char id[] = "@(#)$Id: smrsh.c,v 8.31.4.9 2001/04/24 04:11:51 ca Exp $"; #include <syslog.h> #include <stdlib.h> -#ifndef TRUE -# define TRUE 1 -# define FALSE 0 -#endif /* ! TRUE */ +#include <sm/conf.h> +#include <sm/errstring.h> /* directory in which all commands must reside */ #ifndef CMDDIR -# if defined(HPUX10) || defined(HPUX11) || SOLARIS >= 20800 -# define CMDDIR "/var/adm/sm.bin" -# else /* HPUX10 || HPUX11 || SOLARIS >= 20800 */ -# define CMDDIR "/usr/libexec/sm.bin" -# endif /* HPUX10 || HPUX11 || SOLARIS >= 20800 */ +# ifdef SMRSH_CMDDIR +# define CMDDIR SMRSH_CMDDIR +# else /* SMRSH_CMDDIR */ +# define CMDDIR "/usr/adm/sm.bin" +# endif /* SMRSH_CMDDIR */ #endif /* ! CMDDIR */ /* characters disallowed in the shell "-c" argument */ @@ -88,16 +85,13 @@ static char id[] = "@(#)$Id: smrsh.c,v 8.31.4.9 2001/04/24 04:11:51 ca Exp $"; /* default search path */ #ifndef PATH -# define PATH "/bin:/usr/bin" +# ifdef SMRSH_PATH +# define PATH SMRSH_PATH +# else /* SMRSH_PATH */ +# define PATH "/bin:/usr/bin:/usr/ucb" +# endif /* SMRSH_PATH */ #endif /* ! PATH */ -#ifndef __P -# include "sendmail/cdefs.h" -#endif /* ! __P */ - -extern size_t strlcpy __P((char *, const char *, size_t)); -extern size_t strlcat __P((char *, const char *, size_t)); - char newcmdbuf[1000]; char *prg, *par; @@ -117,8 +111,8 @@ char *prg, *par; void addcmd(s, cmd, len) char *s; - int cmd; - int len; + bool cmd; + size_t len; { if (s == NULL || *s == '\0') return; @@ -126,7 +120,8 @@ addcmd(s, cmd, len) if (sizeof newcmdbuf - strlen(newcmdbuf) <= len + (cmd ? (strlen(CMDDIR) + 1) : 0)) { - fprintf(stderr, "%s: command too long: %s\n", prg, par); + (void)sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: command too long: %s\n", prg, par); #ifndef DEBUG syslog(LOG_WARNING, "command too long: %.40s", par); #endif /* ! DEBUG */ @@ -134,10 +129,10 @@ addcmd(s, cmd, len) } if (cmd) { - (void) strlcat(newcmdbuf, CMDDIR, sizeof newcmdbuf); - (void) strlcat(newcmdbuf, "/", sizeof newcmdbuf); + (void) sm_strlcat(newcmdbuf, CMDDIR, sizeof newcmdbuf); + (void) sm_strlcat(newcmdbuf, "/", sizeof newcmdbuf); } - (void) strlcat(newcmdbuf, s, sizeof newcmdbuf); + (void) sm_strlcat(newcmdbuf, s, sizeof newcmdbuf); } int @@ -149,7 +144,6 @@ main(argc, argv) register char *q; register char *r; register char *cmd; - int i; int isexec; int save_errno; char *newenv[2]; @@ -165,8 +159,8 @@ main(argc, argv) # endif /* ! LOG_MAIL */ #endif /* ! DEBUG */ - (void) strlcpy(pathbuf, "PATH=", sizeof pathbuf); - (void) strlcat(pathbuf, PATH, sizeof pathbuf); + (void) sm_strlcpy(pathbuf, "PATH=", sizeof pathbuf); + (void) sm_strlcat(pathbuf, PATH, sizeof pathbuf); newenv[0] = pathbuf; newenv[1] = NULL; @@ -178,7 +172,8 @@ main(argc, argv) if (argc != 3 || strcmp(argv[1], "-c") != 0) { - fprintf(stderr, "Usage: %s -c command\n", prg); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "Usage: %s -c command\n", prg); #ifndef DEBUG syslog(LOG_ERR, "usage"); #endif /* ! DEBUG */ @@ -201,19 +196,19 @@ main(argc, argv) #endif /* ! DEBUG */ exit(EX_UNAVAILABLE); } - (void) strlcpy(specialbuf, SPECIALS, sizeof specialbuf); + (void) sm_strlcpy(specialbuf, SPECIALS, sizeof specialbuf); for (p = specialbuf; *p != '\0'; p++) *p |= '\200'; - (void) strlcat(specialbuf, SPECIALS, sizeof specialbuf); + (void) sm_strlcat(specialbuf, SPECIALS, sizeof specialbuf); /* ** Do a quick sanity check on command line length. */ - i = strlen(par); - if (i > (sizeof newcmdbuf - sizeof CMDDIR - 2)) + if (strlen(par) > (sizeof newcmdbuf - sizeof CMDDIR - 2)) { - fprintf(stderr, "%s: command too long: %s\n", prg, par); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: command too long: %s\n", prg, par); #ifndef DEBUG syslog(LOG_WARNING, "command too long: %.40s", par); #endif /* ! DEBUG */ @@ -222,7 +217,7 @@ main(argc, argv) q = par; newcmdbuf[0] = '\0'; - isexec = FALSE; + isexec = false; while (*q) { @@ -238,10 +233,11 @@ main(argc, argv) { if (isexec) { - fprintf(stderr, "%s: missing command to exec\n", - prg); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: missing command to exec\n", + prg); #ifndef DEBUG - syslog(LOG_CRIT, "uid %d: missing command to exec", getuid()); + syslog(LOG_CRIT, "uid %d: missing command to exec", (int) getuid()); #endif /* ! DEBUG */ exit(EX_UNAVAILABLE); } @@ -271,15 +267,15 @@ main(argc, argv) /* allow a few shell builtins */ if (strcmp(q, "exec") == 0 && p != NULL) { - addcmd("exec ", FALSE, strlen("exec ")); + addcmd("exec ", false, strlen("exec ")); /* test _next_ arg */ q = ++p; - isexec = TRUE; + isexec = true; continue; } else if (strcmp(q, "exit") == 0 || strcmp(q, "echo") == 0) { - addcmd(cmd, FALSE, strlen(cmd)); + addcmd(cmd, false, strlen(cmd)); /* test following chars */ } else @@ -287,23 +283,24 @@ main(argc, argv) /* ** Check to see if the command name is legal. */ - (void) strlcpy(cmdbuf, CMDDIR, sizeof cmdbuf); - (void) strlcat(cmdbuf, "/", sizeof cmdbuf); - (void) strlcat(cmdbuf, cmd, sizeof cmdbuf); + (void) sm_strlcpy(cmdbuf, CMDDIR, sizeof cmdbuf); + (void) sm_strlcat(cmdbuf, "/", sizeof cmdbuf); + (void) sm_strlcat(cmdbuf, cmd, sizeof cmdbuf); #ifdef DEBUG - printf("Trying %s\n", cmdbuf); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Trying %s\n", cmdbuf); #endif /* DEBUG */ if (access(cmdbuf, X_OK) < 0) { /* oops.... crack attack possiblity */ - fprintf(stderr, - "%s: %s not available for sendmail programs\n", - prg, cmd); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: %s not available for sendmail programs\n", + prg, cmd); if (p != NULL) *p = ' '; #ifndef DEBUG syslog(LOG_CRIT, "uid %d: attempt to use %s", - getuid(), cmd); + (int) getuid(), cmd); #endif /* ! DEBUG */ exit(EX_UNAVAILABLE); } @@ -312,9 +309,9 @@ main(argc, argv) ** Create the actual shell input. */ - addcmd(cmd, TRUE, strlen(cmd)); + addcmd(cmd, true, strlen(cmd)); } - isexec = FALSE; + isexec = false; if (p != NULL) *p = ' '; @@ -322,13 +319,15 @@ main(argc, argv) break; r = strpbrk(p, specialbuf); - if (r == NULL) { - addcmd(p, FALSE, strlen(p)); + if (r == NULL) + { + addcmd(p, false, strlen(p)); break; } #if ALLOWSEMI - if (*r == ';') { - addcmd(p, FALSE, r - p + 1); + if (*r == ';') + { + addcmd(p, false, r - p + 1); q = r + 1; continue; } @@ -336,30 +335,34 @@ main(argc, argv) if ((*r == '&' && *(r + 1) == '&') || (*r == '|' && *(r + 1) == '|')) { - addcmd(p, FALSE, r - p + 2); + addcmd(p, false, r - p + 2); q = r + 2; continue; } - fprintf(stderr, "%s: cannot use %c in command\n", prg, *r); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: cannot use %c in command\n", prg, *r); #ifndef DEBUG syslog(LOG_CRIT, "uid %d: attempt to use %c in command: %s", - getuid(), *r, par); + (int) getuid(), *r, par); #endif /* ! DEBUG */ exit(EX_UNAVAILABLE); } /* end of while *q */ if (isexec) { - fprintf(stderr, "%s: missing command to exec\n", prg); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: missing command to exec\n", prg); #ifndef DEBUG - syslog(LOG_CRIT, "uid %d: missing command to exec", getuid()); + syslog(LOG_CRIT, "uid %d: missing command to exec", + (int) getuid()); #endif /* ! DEBUG */ exit(EX_UNAVAILABLE); } /* make sure we created something */ if (newcmdbuf[0] == '\0') { - fprintf(stderr, "Usage: %s -c command\n", prg); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "Usage: %s -c command\n", prg); #ifndef DEBUG syslog(LOG_ERR, "usage"); #endif /* ! DEBUG */ @@ -371,15 +374,15 @@ main(argc, argv) */ #ifdef DEBUG - printf("%s\n", newcmdbuf); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s\n", newcmdbuf); #endif /* DEBUG */ (void) execle("/bin/sh", "/bin/sh", "-c", newcmdbuf, NULL, newenv); save_errno = errno; #ifndef DEBUG - syslog(LOG_CRIT, "Cannot exec /bin/sh: %m"); + syslog(LOG_CRIT, "Cannot exec /bin/sh: %s", sm_errstring(errno)); #endif /* ! DEBUG */ errno = save_errno; - perror("/bin/sh"); + sm_perror("/bin/sh"); exit(EX_OSFILE); /* NOTREACHED */ return EX_OSFILE; diff --git a/contrib/sendmail/src/aliases.5 b/contrib/sendmail/src/aliases.5 index 1910da5..c6c96f9 100644 --- a/contrib/sendmail/src/aliases.5 +++ b/contrib/sendmail/src/aliases.5 @@ -9,11 +9,11 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: aliases.5,v 8.15.4.2 2000/12/14 23:08:15 gshapiro Exp $ +.\" $Id: aliases.5,v 8.17 2000/12/14 23:09:46 gshapiro Exp $ .\" .\" $FreeBSD$ .\" -.TH ALIASES 5 "$Date: 2000/12/14 23:08:15 $" +.TH ALIASES 5 "$Date: 2000/12/14 23:09:46 $" .SH NAME aliases \- aliases file for sendmail diff --git a/contrib/sendmail/src/conf.c b/contrib/sendmail/src/conf.c index 04b6f8a..cee22e6 100644 --- a/contrib/sendmail/src/conf.c +++ b/contrib/sendmail/src/conf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -11,13 +11,12 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: conf.c,v 8.646.2.2.2.87 2001/07/20 23:56:52 gshapiro Exp $"; -#endif /* ! lint */ +#include <sendmail.h> + +SM_RCSID("@(#)$Id: conf.c,v 8.939 2002/01/09 17:26:28 gshapiro Exp $") /* $FreeBSD$ */ -#include <sendmail.h> #include <sendmail/pathnames.h> # include <sys/ioctl.h> @@ -34,6 +33,7 @@ static char id[] = "@(#)$Id: conf.c,v 8.646.2.2.2.87 2001/07/20 23:56:52 gshapir static void setupmaps __P((void)); static void setupmailers __P((void)); +static void setupqueues __P((void)); static int get_num_procs_online __P((void)); @@ -81,6 +81,7 @@ struct hdrinfo HdrInfo[] = { "errors-to", H_FROM|H_ERRORSTO, NULL }, { "full-name", H_ACHECK, NULL }, { "return-receipt-to", H_RECEIPTTO, NULL }, + { "disposition-notification-to", H_FROM, NULL }, /* destination fields */ { "to", H_RCPT, NULL }, @@ -133,6 +134,7 @@ struct prival PrivacyValues[] = { "needvrfyhelo", PRIV_NEEDVRFYHELO }, { "noexpn", PRIV_NOEXPN }, { "novrfy", PRIV_NOVRFY }, + { "restrictexpand", PRIV_RESTRICTEXPAND }, { "restrictmailq", PRIV_RESTRICTMAILQ }, { "restrictqrun", PRIV_RESTRICTQRUN }, { "noetrn", PRIV_NOETRN }, @@ -147,6 +149,7 @@ struct prival PrivacyValues[] = /* ** DontBlameSendmail values */ + struct dbsval DontBlameSendmailValues[] = { { "safe", DBS_SAFE }, @@ -196,29 +199,30 @@ struct dbsval DontBlameSendmailValues[] = { "dontwarnforwardfileinunsafedirpath", DBS_DONTWARNFORWARDFILEINUNSAFEDIRPATH }, { "insufficiententropy", DBS_INSUFFICIENTENTROPY }, -#if _FFR_UNSAFE_SASL - { "groupreadablesaslfile", DBS_GROUPREADABLESASLFILE }, -#endif /* _FFR_UNSAFE_SASL */ -#if _FFR_UNSAFE_WRITABLE_INCLUDE + { "groupreadablesasldbfile", DBS_GROUPREADABLESASLDBFILE }, + { "groupwritablesasldbfile", DBS_GROUPWRITABLESASLDBFILE }, { "groupwritableforwardfile", DBS_GROUPWRITABLEFORWARDFILE }, { "groupwritableincludefile", DBS_GROUPWRITABLEINCLUDEFILE }, { "worldwritableforwardfile", DBS_WORLDWRITABLEFORWARDFILE }, { "worldwritableincludefile", DBS_WORLDWRITABLEINCLUDEFILE }, -#endif /* _FFR_UNSAFE_WRITABLE_INCLUDE */ + { "groupreadablekeyfile", DBS_GROUPREADABLEKEYFILE }, +#if _FFR_GROUPREADABLEAUTHINFOFILE + { "groupreadableadefaultauthinfofile", + DBS_GROUPREADABLEAUTHINFOFILE }, +#endif /* _FFR_GROUPREADABLEAUTHINFOFILE */ { NULL, 0 } }; - /* ** Miscellaneous stuff. */ int DtableSize = 50; /* max open files; reset in 4.2bsd */ -/* +/* ** SETDEFAULTS -- set default values ** -** Because of the way freezing is done, these must be initialized -** using direct code. +** Some of these must be initialized using direct code since they +** depend on run-time values. So let's do all of them this way. ** ** Parameters: ** e -- the default envelope. @@ -255,12 +259,13 @@ setdefaults(e) WkClassFact = 1800L; /* option z */ WkTimeFact = 90000L; /* option Z */ QueueFactor = WkRecipFact * 20; /* option q */ +#if _FFR_QUARANTINE + QueueMode = QM_NORMAL; /* what queue items to act upon */ +#endif /* _FFR_QUARANTINE */ FileMode = (RealUid != geteuid()) ? 0644 : 0600; /* option F */ -#if _FFR_QUEUE_FILE_MODE QueueFileMode = (RealUid != geteuid()) ? 0644 : 0600; /* option QueueFileMode */ -#endif /* _FFR_QUEUE_FILE_MODE */ if (((pw = sm_getpwnam("mailnull")) != NULL && pw->pw_uid != 0) || ((pw = sm_getpwnam("sendmail")) != NULL && pw->pw_uid != 0) || @@ -278,24 +283,30 @@ setdefaults(e) } TrustedUid = 0; if (tTd(37, 4)) - dprintf("setdefaults: DefUser=%s, DefUid=%d, DefGid=%d\n", + sm_dprintf("setdefaults: DefUser=%s, DefUid=%d, DefGid=%d\n", DefUser != NULL ? DefUser : "<1:1>", (int) DefUid, (int) DefGid); CheckpointInterval = 10; /* option C */ MaxHopCount = 25; /* option h */ set_delivery_mode(SM_FORK, e); /* option d */ e->e_errormode = EM_PRINT; /* option e */ - e->e_queuedir = NOQDIR; + e->e_qgrp = NOQGRP; + e->e_qdir = NOQDIR; + e->e_xfqgrp = NOQGRP; + e->e_xfqdir = NOQDIR; e->e_ctime = curtime(); - SevenBitInput = FALSE; /* option 7 */ + SevenBitInput = false; /* option 7 */ MaxMciCache = 1; /* option k */ MciCacheTimeout = 5 MINUTES; /* option K */ LogLevel = 9; /* option L */ - inittimeouts(NULL, FALSE); /* option r */ +#if MILTER + MilterLogLevel = -1; +#endif /* MILTER */ + inittimeouts(NULL, false); /* option r */ PrivacyFlags = PRIV_PUBLIC; /* option p */ - MeToo = TRUE; /* option m */ - SendMIMEErrors = TRUE; /* option f */ - SuperSafe = TRUE; /* option s */ + MeToo = true; /* option m */ + SendMIMEErrors = true; /* option f */ + SuperSafe = SAFE_REALLY; /* option s */ clrbitmap(DontBlameSendmail); /* DontBlameSendmail option */ #if MIME8TO7 MimeMode = MM_CVTMIME|MM_PASS8BIT; /* option 8 */ @@ -316,14 +327,20 @@ setdefaults(e) MaxRuleRecursion = MAXRULERECURSION; MaxAliasRecursion = 10; MaxMacroRecursion = 10; - ColonOkInAddr = TRUE; - DontLockReadFiles = TRUE; + ColonOkInAddr = true; + DontLockReadFiles = true; + DontProbeInterfaces = DPI_PROBEALL; DoubleBounceAddr = "postmaster"; MaxHeadersLength = MAXHDRSLEN; MaxForwardEntries = 0; + FastSplit = 1; #if SASL AuthMechanisms = newstr(AUTH_MECHANISMS); + MaxSLBits = INT_MAX; #endif /* SASL */ +#if STARTTLS + TLS_Srv_Opts = TLS_I_SRV; +#endif /* STARTTLS */ #ifdef HESIOD_INIT HesiodContext = NULL; #endif /* HESIOD_INIT */ @@ -346,10 +363,11 @@ setdefaults(e) XscriptFileBufferSize = 4096; for (i = 0; i < MAXRWSETS; i++) RuleSetNames[i] = NULL; -#if _FFR_MILTER +#if MILTER InputFilters[0] = NULL; -#endif /* _FFR_MILTER */ +#endif /* MILTER */ setupmaps(); + setupqueues(); setupmailers(); setupheaders(); } @@ -367,13 +385,32 @@ setdefuser() DefUser = defuserbuf; defpwent = sm_getpwuid(DefUid); - snprintf(defuserbuf, sizeof defuserbuf, "%s", - defpwent == NULL ? "nobody" : defpwent->pw_name); + (void) sm_strlcpy(defuserbuf, + (defpwent == NULL || defpwent->pw_name == NULL) + ? "nobody" : defpwent->pw_name, + sizeof defuserbuf); if (tTd(37, 4)) - dprintf("setdefuser: DefUid=%d, DefUser=%s\n", - (int) DefUid, DefUser); + sm_dprintf("setdefuser: DefUid=%d, DefUser=%s\n", + (int) DefUid, DefUser); +} +/* +** SETUPQUEUES -- initialize default queues +** +** The mqueue QUEUE structure gets filled in after readcf() but +** we need something to point to now for the mailer setup, +** which use "mqueue" as default queue. +*/ + +static void +setupqueues() +{ + char buf[100]; + + MaxRunnersPerQueue = 1; + (void) sm_strlcpy(buf, "mqueue, P=/var/spool/mqueue", sizeof buf); + makequeue(buf, false); } -/* +/* ** SETUPMAILERS -- initialize default mailers */ @@ -382,20 +419,20 @@ setupmailers() { char buf[100]; - (void) strlcpy(buf, "prog, P=/bin/sh, F=lsouDq9, T=X-Unix/X-Unix/X-Unix, A=sh -c \201u", - sizeof buf); + (void) sm_strlcpy(buf, "prog, P=/bin/sh, F=lsouDq9, T=X-Unix/X-Unix/X-Unix, A=sh -c \201u", + sizeof buf); makemailer(buf); - (void) strlcpy(buf, "*file*, P=[FILE], F=lsDFMPEouq9, T=X-Unix/X-Unix/X-Unix, A=FILE \201u", - sizeof buf); + (void) sm_strlcpy(buf, "*file*, P=[FILE], F=lsDFMPEouq9, T=X-Unix/X-Unix/X-Unix, A=FILE \201u", + sizeof buf); makemailer(buf); - (void) strlcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE \201u", - sizeof buf); + (void) sm_strlcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE \201u", + sizeof buf); makemailer(buf); initerrmailers(); } -/* +/* ** SETUPMAPS -- set up map classes */ @@ -422,7 +459,7 @@ setupmaps() { register STAB *s; -#ifdef NEWDB +#if NEWDB MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE, map_parseargs, hash_map_open, db_map_close, db_map_lookup, db_map_store); @@ -432,37 +469,32 @@ setupmaps() db_map_lookup, db_map_store); #endif /* NEWDB */ -#ifdef NDBM +#if NDBM MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE, map_parseargs, ndbm_map_open, ndbm_map_close, ndbm_map_lookup, ndbm_map_store); #endif /* NDBM */ -#ifdef NIS +#if NIS MAPDEF("nis", NULL, MCF_ALIASOK, map_parseargs, nis_map_open, null_map_close, nis_map_lookup, null_map_store); #endif /* NIS */ -#ifdef NISPLUS +#if NISPLUS MAPDEF("nisplus", NULL, MCF_ALIASOK, map_parseargs, nisplus_map_open, null_map_close, nisplus_map_lookup, null_map_store); #endif /* NISPLUS */ -#ifdef LDAPMAP - MAPDEF("ldap", NULL, MCF_ALIASOK, +#if LDAPMAP + MAPDEF("ldap", NULL, MCF_ALIASOK|MCF_NOTPERSIST, ldapmap_parseargs, ldapmap_open, ldapmap_close, ldapmap_lookup, null_map_store); - - /* Deprecated */ - MAPDEF("ldapx", NULL, MCF_ALIASOK, - ldapx_map_parseargs, ldapmap_open, ldapmap_close, - ldapmap_lookup, null_map_store); #endif /* LDAPMAP */ -#ifdef PH_MAP - MAPDEF("ph", NULL, 0, +#if PH_MAP + MAPDEF("ph", NULL, MCF_NOTPERSIST, ph_map_parseargs, ph_map_open, ph_map_close, ph_map_lookup, null_map_store); #endif /* PH_MAP */ @@ -474,9 +506,9 @@ setupmaps() nsd_map_lookup, null_map_store); #endif /* MAP_NSD */ -#ifdef HESIOD +#if HESIOD MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY, - map_parseargs, hes_map_open, null_map_close, + map_parseargs, hes_map_open, hes_map_close, hes_map_lookup, null_map_store); #endif /* HESIOD */ @@ -493,6 +525,14 @@ setupmaps() #endif /* 0 */ #if NAMED_BIND +# if DNSMAP + MAPDEF("dns", NULL, 0, + dns_map_parseargs, dns_map_open, null_map_close, + dns_map_lookup, null_map_store); +# endif /* DNSMAP */ +#endif /* NAMED_BIND */ + +#if NAMED_BIND /* best MX DNS lookup */ MAPDEF("bestmx", NULL, MCF_OPTFILE, map_parseargs, null_map_open, null_map_close, @@ -525,7 +565,7 @@ setupmaps() dequote_init, null_map_open, null_map_close, dequote_map, null_map_store); -#ifdef MAP_REGEX +#if MAP_REGEX MAPDEF("regex", NULL, 0, regex_map_init, null_map_open, null_map_close, regex_map_lookup, null_map_store); @@ -583,7 +623,7 @@ setupmaps() } #undef MAPDEF -/* +/* ** INITHOSTMAPS -- initial host-dependent maps ** ** This should act as an interface to any local service switch @@ -623,41 +663,41 @@ inithostmaps() if (strcmp(maptype[i], "files") == 0 && stab("hosts.files", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts", + (void) sm_strlcpy(buf, "hosts.files text -k 0 -v 1 /etc/hosts", sizeof buf); (void) makemapentry(buf); } # if NAMED_BIND else if (strcmp(maptype[i], "dns") == 0 && - stab("hosts.dns", ST_MAP, ST_FIND) == NULL) + stab("hosts.dns", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "hosts.dns dns A", sizeof buf); + (void) sm_strlcpy(buf, "hosts.dns dns A", sizeof buf); (void) makemapentry(buf); } # endif /* NAMED_BIND */ -# ifdef NISPLUS +# if NISPLUS else if (strcmp(maptype[i], "nisplus") == 0 && - stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL) + stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "hosts.nisplus nisplus -k name -v address hosts.org_dir", + (void) sm_strlcpy(buf, "hosts.nisplus nisplus -k name -v address hosts.org_dir", sizeof buf); (void) makemapentry(buf); } # endif /* NISPLUS */ -# ifdef NIS +# if NIS else if (strcmp(maptype[i], "nis") == 0 && - stab("hosts.nis", ST_MAP, ST_FIND) == NULL) + stab("hosts.nis", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "hosts.nis nis -k 0 -v 1 hosts.byname", + (void) sm_strlcpy(buf, "hosts.nis nis -k 0 -v 1 hosts.byname", sizeof buf); (void) makemapentry(buf); } # endif /* NIS */ # if NETINFO - else if (strcmp(maptype[i], "netinfo") == 0) && - stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL) + else if (strcmp(maptype[i], "netinfo") == 0 && + stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "hosts.netinfo netinfo -v name /machines", + (void) sm_strlcpy(buf, "hosts.netinfo netinfo -v name /machines", sizeof buf); (void) makemapentry(buf); } @@ -672,10 +712,10 @@ inithostmaps() if (stab("host", ST_MAP, ST_FIND) == NULL) { /* user didn't initialize: set up host map */ - (void) strlcpy(buf, "host host", sizeof buf); + (void) sm_strlcpy(buf, "host host", sizeof buf); #if NAMED_BIND if (ConfigLevel >= 2) - (void) strlcat(buf, " -a. -D", sizeof buf); + (void) sm_strlcat(buf, " -a. -D", sizeof buf); #endif /* NAMED_BIND */ (void) makemapentry(buf); } @@ -690,41 +730,42 @@ inithostmaps() if (strcmp(maptype[i], "files") == 0 && stab("aliases.files", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "aliases.files null", sizeof buf); + (void) sm_strlcpy(buf, "aliases.files null", + sizeof buf); (void) makemapentry(buf); } -#ifdef NISPLUS +#if NISPLUS else if (strcmp(maptype[i], "nisplus") == 0 && - stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL) + stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir", + (void) sm_strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir", sizeof buf); (void) makemapentry(buf); } #endif /* NISPLUS */ -#ifdef NIS +#if NIS else if (strcmp(maptype[i], "nis") == 0 && - stab("aliases.nis", ST_MAP, ST_FIND) == NULL) + stab("aliases.nis", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "aliases.nis nis mail.aliases", + (void) sm_strlcpy(buf, "aliases.nis nis mail.aliases", sizeof buf); (void) makemapentry(buf); } #endif /* NIS */ #if NETINFO else if (strcmp(maptype[i], "netinfo") == 0 && - stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL) + stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "aliases.netinfo netinfo -z, /aliases", + (void) sm_strlcpy(buf, "aliases.netinfo netinfo -z, /aliases", sizeof buf); (void) makemapentry(buf); } #endif /* NETINFO */ -#ifdef HESIOD +#if HESIOD else if (strcmp(maptype[i], "hesiod") == 0 && - stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL) + stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "aliases.hesiod hesiod aliases", + (void) sm_strlcpy(buf, "aliases.hesiod hesiod aliases", sizeof buf); (void) makemapentry(buf); } @@ -732,7 +773,7 @@ inithostmaps() } if (stab("aliases", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "aliases switch aliases", sizeof buf); + (void) sm_strlcpy(buf, "aliases switch aliases", sizeof buf); (void) makemapentry(buf); } @@ -747,45 +788,45 @@ inithostmaps() if (strcmp(maptype[i], "files") == 0 && stab("users.files", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd", + (void) sm_strlcpy(buf, "users.files text -m -z: -k0 -v6 /etc/passwd", sizeof buf); (void) makemapentry(buf); } -# ifdef NISPLUS +# if NISPLUS else if (strcmp(maptype[i], "nisplus") == 0 && stab("users.nisplus", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "users.nisplus nisplus -m -kname -vhome passwd.org_dir", + (void) sm_strlcpy(buf, "users.nisplus nisplus -m -kname -vhome passwd.org_dir", sizeof buf); (void) makemapentry(buf); } # endif /* NISPLUS */ -# ifdef NIS +# if NIS else if (strcmp(maptype[i], "nis") == 0 && stab("users.nis", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "users.nis nis -m passwd.byname", + (void) sm_strlcpy(buf, "users.nis nis -m passwd.byname", sizeof buf); (void) makemapentry(buf); } # endif /* NIS */ -# ifdef HESIOD - else if (strcmp(maptype[i], "hesiod") == 0) && - stab("users.hesiod", ST_MAP, ST_FIND) == NULL) +# if HESIOD + else if (strcmp(maptype[i], "hesiod") == 0 && + stab("users.hesiod", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "users.hesiod hesiod", sizeof buf); + (void) sm_strlcpy(buf, "users.hesiod hesiod", sizeof buf); (void) makemapentry(buf); } # endif /* HESIOD */ } if (stab("users", ST_MAP, ST_FIND) == NULL) { - (void) strlcpy(buf, "users switch -m passwd", sizeof buf); + (void) sm_strlcpy(buf, "users switch -m passwd", sizeof buf); (void) makemapentry(buf); } #endif /* 0 */ } -/* +/* ** SWITCH_MAP_FIND -- find the list of types associated with a map ** ** This is the system-dependent interface to the service switch. @@ -809,6 +850,12 @@ inithostmaps() # define _USE_SUN_NSSWITCH_ #endif /* defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) */ +#if _FFR_HPUX_NSSWITCH +# ifdef __hpux +# define _USE_SUN_NSSWITCH_ +# endif /* __hpux */ +#endif /* _FFR_HPUX_NSSWITCH */ + #ifdef _USE_SUN_NSSWITCH_ # include <nsswitch.h> #endif /* _USE_SUN_NSSWITCH_ */ @@ -921,15 +968,16 @@ switch_map_find(service, maptype, mapreturn) */ STAB *st; + static time_t servicecachetime; /* time service switch was cached */ time_t now = curtime(); for (svcno = 0; svcno < MAXMAPACTIONS; svcno++) mapreturn[svcno] = 0; - if ((now - ServiceCacheTime) > (time_t) ServiceCacheMaxAge) + if ((now - servicecachetime) > (time_t) ServiceCacheMaxAge) { /* (re)read service switch */ - register FILE *fp; + register SM_FILE_T *fp; long sff = SFF_REGONLY|SFF_OPENASROOT|SFF_NOLOCK; if (!bitnset(DBS_LINKEDSERVICESWITCHFILEINWRITABLEDIR, @@ -937,13 +985,14 @@ switch_map_find(service, maptype, mapreturn) sff |= SFF_NOWLINK; if (ConfigFileRead) - ServiceCacheTime = now; + servicecachetime = now; fp = safefopen(ServiceSwitchFile, O_RDONLY, 0, sff); if (fp != NULL) { char buf[MAXLINE]; - while (fgets(buf, sizeof buf, fp) != NULL) + while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf, + sizeof buf) != NULL) { register char *p; @@ -978,7 +1027,7 @@ switch_map_find(service, maptype, mapreturn) st = stab(buf, ST_SERVICE, ST_ENTER); if (st->s_service[0] != NULL) - sm_free((void *) st->s_service[0]); + sm_free((void *) st->s_service[0]); /* XXX */ p = newstr(p); for (svcno = 0; svcno < MAXMAPSTACK; ) { @@ -995,7 +1044,7 @@ switch_map_find(service, maptype, mapreturn) if (svcno < MAXMAPSTACK) st->s_service[svcno] = NULL; } - (void) fclose(fp); + (void) sm_io_close(fp, SM_TIME_DEFAULT); } } @@ -1031,10 +1080,10 @@ switch_map_find(service, maptype, mapreturn) maptype[svcno++] = "netinfo"; # endif /* defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) */ # ifdef AUTO_NIS_ALIASES -# ifdef NISPLUS +# if NISPLUS maptype[svcno++] = "nisplus"; # endif /* NISPLUS */ -# ifdef NIS +# if NIS maptype[svcno++] = "nis"; # endif /* NIS */ # endif /* AUTO_NIS_ALIASES */ @@ -1062,7 +1111,7 @@ switch_map_find(service, maptype, mapreturn) return -1; #endif /* !defined(_USE_SUN_NSSWITCH_) */ } -/* +/* ** USERNAME -- return the user id of the logged in user. ** ** Parameters: @@ -1093,19 +1142,18 @@ username() { pw = sm_getpwuid(RealUid); if (pw != NULL) - myname = newstr(pw->pw_name); + myname = pw->pw_name; } else { uid_t uid = RealUid; - myname = newstr(myname); if ((pw = sm_getpwnam(myname)) == NULL || (uid != 0 && uid != pw->pw_uid)) { pw = sm_getpwuid(uid); if (pw != NULL) - myname = newstr(pw->pw_name); + myname = pw->pw_name; } } if (myname == NULL || myname[0] == '\0') @@ -1113,11 +1161,14 @@ username() syserr("554 5.3.0 Who are you?"); myname = "postmaster"; } + else if (strpbrk(myname, ",;:/|\"\\") != NULL) + myname = addquotes(myname, NULL); + else + myname = sm_pstrdup_x(myname); } - return myname; } -/* +/* ** TTYPATH -- Get the path of the user's tty ** ** Returns the pathname of the user's tty. Returns NULL if @@ -1171,7 +1222,7 @@ ttypath() /* looks good */ return pathn; } -/* +/* ** CHECKCOMPAT -- check for From and To person compatible. ** ** This routine can be supplied on a per-installation basis @@ -1205,7 +1256,7 @@ checkcompat(to, e) register ENVELOPE *e; { if (tTd(49, 1)) - dprintf("checkcompat(to=%s, from=%s)\n", + sm_dprintf("checkcompat(to=%s, from=%s)\n", to->q_paddr, e->e_from.q_paddr); #ifdef EXAMPLE_CODE @@ -1224,255 +1275,7 @@ checkcompat(to, e) #endif /* EXAMPLE_CODE */ return EX_OK; } -/* -** SETSIGNAL -- set a signal handler -** -** This is essentially old BSD "signal(3)". -** -** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD -** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE -** DOING. -*/ - -sigfunc_t -setsignal(sig, handler) - int sig; - sigfunc_t handler; -{ -# if defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3)) - struct sigaction n, o; -# endif /* defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3)) */ - - /* - ** First, try for modern signal calls - ** and restartable syscalls - */ - -# ifdef SA_RESTART - memset(&n, '\0', sizeof n); -# if USE_SA_SIGACTION - n.sa_sigaction = (void(*)(int, siginfo_t *, void *)) handler; - n.sa_flags = SA_RESTART|SA_SIGINFO; -# else /* USE_SA_SIGACTION */ - n.sa_handler = handler; - n.sa_flags = SA_RESTART; -# endif /* USE_SA_SIGACTION */ - if (sigaction(sig, &n, &o) < 0) - return SIG_ERR; - return o.sa_handler; -# else /* SA_RESTART */ - - /* - ** Else check for SYS5SIGNALS or - ** BSD4_3 signals - */ - -# if defined(SYS5SIGNALS) || defined(BSD4_3) -# ifdef BSD4_3 - return signal(sig, handler); -# else /* BSD4_3 */ - return sigset(sig, handler); -# endif /* BSD4_3 */ -# else /* defined(SYS5SIGNALS) || defined(BSD4_3) */ - - /* - ** Finally, if nothing else is available, - ** go for a default - */ - - memset(&n, '\0', sizeof n); - n.sa_handler = handler; - if (sigaction(sig, &n, &o) < 0) - return SIG_ERR; - return o.sa_handler; -# endif /* defined(SYS5SIGNALS) || defined(BSD4_3) */ -# endif /* SA_RESTART */ -} -/* -** ALLSIGNALS -- act on all signals -** -** Parameters: -** block -- whether to block or release all signals. -** -** Returns: -** none. -*/ - -void -allsignals(block) - bool block; -{ -# ifdef BSD4_3 -# ifndef sigmask -# define sigmask(s) (1 << ((s) - 1)) -# endif /* ! sigmask */ - if (block) - { - int mask = 0; - - mask |= sigmask(SIGALRM); - mask |= sigmask(SIGCHLD); - mask |= sigmask(SIGHUP); - mask |= sigmask(SIGINT); - mask |= sigmask(SIGTERM); - mask |= sigmask(SIGUSR1); - - (void) sigblock(mask); - } - else - sigsetmask(0); -# else /* BSD4_3 */ -# ifdef ALTOS_SYSTEM_V - if (block) - { - (void) sigset(SIGALRM, SIG_HOLD); - (void) sigset(SIGCHLD, SIG_HOLD); - (void) sigset(SIGHUP, SIG_HOLD); - (void) sigset(SIGINT, SIG_HOLD); - (void) sigset(SIGTERM, SIG_HOLD); - (void) sigset(SIGUSR1, SIG_HOLD); - } - else - { - (void) sigset(SIGALRM, SIG_DFL); - (void) sigset(SIGCHLD, SIG_DFL); - (void) sigset(SIGHUP, SIG_DFL); - (void) sigset(SIGINT, SIG_DFL); - (void) sigset(SIGTERM, SIG_DFL); - (void) sigset(SIGUSR1, SIG_DFL); - } -# else /* ALTOS_SYSTEM_V */ - sigset_t sset; - - (void) sigemptyset(&sset); - (void) sigaddset(&sset, SIGALRM); - (void) sigaddset(&sset, SIGCHLD); - (void) sigaddset(&sset, SIGHUP); - (void) sigaddset(&sset, SIGINT); - (void) sigaddset(&sset, SIGTERM); - (void) sigaddset(&sset, SIGUSR1); - (void) sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sset, NULL); -# endif /* ALTOS_SYSTEM_V */ -# endif /* BSD4_3 */ -} -/* -** BLOCKSIGNAL -- hold a signal to prevent delivery -** -** Parameters: -** sig -- the signal to block. -** -** Returns: -** 1 signal was previously blocked -** 0 signal was not previously blocked -** -1 on failure. -*/ - -int -blocksignal(sig) - int sig; -{ -# ifdef BSD4_3 -# ifndef sigmask -# define sigmask(s) (1 << ((s) - 1)) -# endif /* ! sigmask */ - return (sigblock(sigmask(sig)) & sigmask(sig)) != 0; -# else /* BSD4_3 */ -# ifdef ALTOS_SYSTEM_V - sigfunc_t handler; - - handler = sigset(sig, SIG_HOLD); - if (handler == SIG_ERR) - return -1; - else - return handler == SIG_HOLD; -# else /* ALTOS_SYSTEM_V */ - sigset_t sset, oset; - - (void) sigemptyset(&sset); - (void) sigaddset(&sset, sig); - if (sigprocmask(SIG_BLOCK, &sset, &oset) < 0) - return -1; - else - return sigismember(&oset, sig); -# endif /* ALTOS_SYSTEM_V */ -# endif /* BSD4_3 */ -} -/* -** RELEASESIGNAL -- release a held signal -** -** Parameters: -** sig -- the signal to release. -** -** Returns: -** 1 signal was previously blocked -** 0 signal was not previously blocked -** -1 on failure. -*/ - -int -releasesignal(sig) - int sig; -{ -# ifdef BSD4_3 - return (sigsetmask(sigblock(0) & ~sigmask(sig)) & sigmask(sig)) != 0; -# else /* BSD4_3 */ -# ifdef ALTOS_SYSTEM_V - sigfunc_t handler; - - handler = sigset(sig, SIG_HOLD); - if (sigrelse(sig) < 0) - return -1; - else - return handler == SIG_HOLD; -# else /* ALTOS_SYSTEM_V */ - sigset_t sset, oset; - - (void) sigemptyset(&sset); - (void) sigaddset(&sset, sig); - if (sigprocmask(SIG_UNBLOCK, &sset, &oset) < 0) - return -1; - else - return sigismember(&oset, sig); -# endif /* ALTOS_SYSTEM_V */ -# endif /* BSD4_3 */ -} -/* -** HOLDSIGS -- arrange to hold all signals -** -** Parameters: -** none. -** -** Returns: -** none. -** -** Side Effects: -** Arranges that signals are held. -*/ - -void -holdsigs() -{ -} -/* -** RLSESIGS -- arrange to release all signals -** -** This undoes the effect of holdsigs. -** -** Parameters: -** none. -** -** Returns: -** none. -** -** Side Effects: -** Arranges that signals are released. -*/ - -void -rlsesigs() -{ -} -/* +/* ** INIT_MD -- do machine dependent initializations ** ** Systems that have global modes that should be set should do @@ -1535,7 +1338,7 @@ init_md(argc, argv) VendorCode = VENDOR_BERKELEY; #endif /* VENDOR_DEFAULT */ } -/* +/* ** INIT_VENDOR_MACROS -- vendor-dependent macro initializations ** ** Called once, on startup. @@ -1555,7 +1358,7 @@ init_vendor_macros(e) register ENVELOPE *e; { } -/* +/* ** GETLA -- get the current load average ** ** This code stolen from la.c. @@ -1648,9 +1451,10 @@ struct nlist Nl[] = # endif /* _AUX_SOURCE */ # define X_AVENRUN 0 -static int +int getla() { + int j; static int kmem = -1; # if LA_TYPE == LA_INT long avenrun[3]; @@ -1667,7 +1471,7 @@ getla() if (kmem < 0) { # ifdef _AUX_SOURCE - (void) strlcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN, + (void) sm_strlcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN, sizeof Nl[X_AVENRUN].n_name); Nl[1].n_name[0] = '\0'; # endif /* _AUX_SOURCE */ @@ -1679,14 +1483,14 @@ getla() # endif /* defined(_AIX3) || defined(_AIX4) */ { if (tTd(3, 1)) - dprintf("getla: nlist(%s): %s\n", _PATH_UNIX, - errstring(errno)); + sm_dprintf("getla: nlist(%s): %s\n", _PATH_UNIX, + sm_errstring(errno)); return -1; } if (Nl[X_AVENRUN].n_value == 0) { if (tTd(3, 1)) - dprintf("getla: nlist(%s, %s) ==> 0\n", + sm_dprintf("getla: nlist(%s, %s) ==> 0\n", _PATH_UNIX, LA_AVENRUN); return -1; } @@ -1698,52 +1502,61 @@ getla() if (kmem < 0) { if (tTd(3, 1)) - dprintf("getla: open(/dev/kmem): %s\n", - errstring(errno)); + sm_dprintf("getla: open(/dev/kmem): %s\n", + sm_errstring(errno)); + return -1; + } + if ((j = fcntl(kmem, F_GETFD, 0)) < 0 || + fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0) + { + if (tTd(3, 1)) + sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n", + sm_errstring(errno)); + (void) close(kmem); + kmem = -1; return -1; } - (void) fcntl(kmem, F_SETFD, FD_CLOEXEC); } if (tTd(3, 20)) - dprintf("getla: symbol address = %#lx\n", - (u_long) Nl[X_AVENRUN].n_value); + sm_dprintf("getla: symbol address = %#lx\n", + (unsigned long) Nl[X_AVENRUN].n_value); if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 || read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) { /* thank you Ian */ if (tTd(3, 1)) - dprintf("getla: lseek or read: %s\n", - errstring(errno)); + sm_dprintf("getla: lseek or read: %s\n", + sm_errstring(errno)); return -1; } # if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) if (tTd(3, 5)) { # if LA_TYPE == LA_SHORT - dprintf("getla: avenrun = %d", avenrun[0]); + sm_dprintf("getla: avenrun = %d", avenrun[0]); if (tTd(3, 15)) - dprintf(", %d, %d", avenrun[1], avenrun[2]); + sm_dprintf(", %d, %d", avenrun[1], avenrun[2]); # else /* LA_TYPE == LA_SHORT */ - dprintf("getla: avenrun = %ld", avenrun[0]); + sm_dprintf("getla: avenrun = %ld", avenrun[0]); if (tTd(3, 15)) - dprintf(", %ld, %ld", avenrun[1], avenrun[2]); + sm_dprintf(", %ld, %ld", avenrun[1], avenrun[2]); # endif /* LA_TYPE == LA_SHORT */ - dprintf("\n"); + sm_dprintf("\n"); } if (tTd(3, 1)) - dprintf("getla: %d\n", + sm_dprintf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT); return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); # else /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) */ if (tTd(3, 5)) { - dprintf("getla: avenrun = %g", avenrun[0]); + sm_dprintf("getla: avenrun = %g", avenrun[0]); if (tTd(3, 15)) - dprintf(", %g, %g", avenrun[1], avenrun[2]); - dprintf("\n"); + sm_dprintf(", %g, %g", avenrun[1], avenrun[2]); + sm_dprintf("\n"); } if (tTd(3, 1)) - dprintf("getla: %d\n", (int) (avenrun[0] +0.5)); + sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5)); return ((int) (avenrun[0] + 0.5)); # endif /* (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT) */ } @@ -1754,9 +1567,10 @@ getla() # include <sys/ksym.h> -static int +int getla() { + int j; static int kmem = -1; long avenrun[3]; extern int errno; @@ -1768,11 +1582,20 @@ getla() if (kmem < 0) { if (tTd(3, 1)) - dprintf("getla: open(/dev/kmem): %s\n", - errstring(errno)); + sm_dprintf("getla: open(/dev/kmem): %s\n", + sm_errstring(errno)); + return -1; + } + if ((j = fcntl(kmem, F_GETFD, 0)) < 0 || + fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0) + { + if (tTd(3, 1)) + sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n", + sm_errstring(errno)); + (void) close(kmem); + kmem = -1; return -1; } - (void) fcntl(kmem, F_SETFD, FD_CLOEXEC); } mirk.mirk_symname = LA_AVENRUN; mirk.mirk_buf = avenrun; @@ -1780,19 +1603,19 @@ getla() if (ioctl(kmem, MIOC_READKSYM, &mirk) < 0) { if (tTd(3, 1)) - dprintf("getla: ioctl(MIOC_READKSYM) failed: %s\n", - errstring(errno)); + sm_dprintf("getla: ioctl(MIOC_READKSYM) failed: %s\n", + sm_errstring(errno)); return -1; } if (tTd(3, 5)) { - dprintf("getla: avenrun = %d", avenrun[0]); + sm_dprintf("getla: avenrun = %d", avenrun[0]); if (tTd(3, 15)) - dprintf(", %d, %d", avenrun[1], avenrun[2]); - dprintf("\n"); + sm_dprintf(", %d, %d", avenrun[1], avenrun[2]); + sm_dprintf("\n"); } if (tTd(3, 1)) - dprintf("getla: %d\n", + sm_dprintf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT); return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); } @@ -1803,7 +1626,7 @@ getla() # include <sys/dg_sys_info.h> -static int +int getla() { struct dg_sys_info_load_info load_info; @@ -1812,7 +1635,7 @@ getla() DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); if (tTd(3, 1)) - dprintf("getla: %d\n", (int) (load_info.one_minute + 0.5)); + sm_dprintf("getla: %d\n", (int) (load_info.one_minute + 0.5)); return ((int) (load_info.one_minute + 0.5)); } @@ -1834,7 +1657,7 @@ struct pst_swapinfo; # include <sys/param.h> # include <sys/pstat.h> -static int +int getla() { struct pst_dynamic pstd; @@ -1844,7 +1667,7 @@ getla() return 0; if (tTd(3, 1)) - dprintf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5)); + sm_dprintf("getla: %d\n", (int) (pstd.psd_avg_1_min + 0.5)); return (int) (pstd.psd_avg_1_min + 0.5); } @@ -1853,7 +1676,7 @@ getla() #if LA_TYPE == LA_SUBR -static int +int getla() { double avenrun[3]; @@ -1861,12 +1684,12 @@ getla() if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0) { if (tTd(3, 1)) - dprintf("getla: getloadavg failed: %s", - errstring(errno)); + sm_dprintf("getla: getloadavg failed: %s", + sm_errstring(errno)); return -1; } if (tTd(3, 1)) - dprintf("getla: %d\n", (int) (avenrun[0] +0.5)); + sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5)); return ((int) (avenrun[0] + 0.5)); } @@ -1884,7 +1707,7 @@ getla() # include <mach.h> # endif /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */ -static int +int getla() { processor_set_t default_set; @@ -1897,8 +1720,8 @@ getla() if (error != KERN_SUCCESS) { if (tTd(3, 1)) - dprintf("getla: processor_set_default failed: %s", - errstring(errno)); + sm_dprintf("getla: processor_set_default failed: %s", + sm_errstring(errno)); return -1; } info_count = PROCESSOR_SET_BASIC_INFO_COUNT; @@ -1907,12 +1730,12 @@ getla() &info_count) != KERN_SUCCESS) { if (tTd(3, 1)) - dprintf("getla: processor_set_info failed: %s", - errstring(errno)); + sm_dprintf("getla: processor_set_info failed: %s", + sm_errstring(errno)); return -1; } if (tTd(3, 1)) - dprintf("getla: %d\n", + sm_dprintf("getla: %d\n", (int) ((info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE)); return (int) (info.load_average + (LOAD_SCALE / 2)) / LOAD_SCALE; @@ -1921,6 +1744,12 @@ getla() #endif /* LA_TYPE == LA_MACH */ #if LA_TYPE == LA_PROCSTR +# if SM_CONF_BROKEN_STRTOD + ERROR: This OS has most likely a broken strtod() implemenentation. + ERROR: The function is required for getla(). + ERROR: Check the compilation options _LA_PROCSTR and + ERROR: _SM_CONF_BROKEN_STRTOD (without the leading _). +# endif /* SM_CONF_BROKEN_STRTOD */ /* ** Read /proc/loadavg for the load average. This is assumed to be @@ -1934,33 +1763,34 @@ getla() # define _PATH_LOADAVG "/proc/loadavg" # endif /* ! _PATH_LOADAVG */ -static int +int getla() { double avenrun; register int result; - FILE *fp; + SM_FILE_T *fp; - fp = fopen(_PATH_LOADAVG, "r"); + fp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_LOADAVG, SM_IO_RDONLY, + NULL); if (fp == NULL) { if (tTd(3, 1)) - dprintf("getla: fopen(%s): %s\n", - _PATH_LOADAVG, errstring(errno)); + sm_dprintf("getla: sm_io_open(%s): %s\n", + _PATH_LOADAVG, sm_errstring(errno)); return -1; } - result = fscanf(fp, "%lf", &avenrun); - (void) fclose(fp); + result = sm_io_fscanf(fp, SM_TIME_DEFAULT, "%lf", &avenrun); + (void) sm_io_close(fp, SM_TIME_DEFAULT); if (result != 1) { if (tTd(3, 1)) - dprintf("getla: fscanf() = %d: %s\n", - result, errstring(errno)); + sm_dprintf("getla: sm_io_fscanf() = %d: %s\n", + result, sm_errstring(errno)); return -1; } if (tTd(3, 1)) - dprintf("getla(): %.2f\n", avenrun); + sm_dprintf("getla(): %.2f\n", avenrun); return ((int) (avenrun + 0.5)); } @@ -1971,8 +1801,10 @@ getla() # include <sys/sysmp.h> -int getla(void) +int +getla(void) { + int j; static int kmem = -1; int avenrun[3]; @@ -1982,32 +1814,41 @@ int getla(void) if (kmem < 0) { if (tTd(3, 1)) - dprintf("getla: open(%s): %s\n", _PATH_KMEM, - errstring(errno)); + sm_dprintf("getla: open(%s): %s\n", _PATH_KMEM, + sm_errstring(errno)); + return -1; + } + if ((j = fcntl(kmem, F_GETFD, 0)) < 0 || + fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0) + { + if (tTd(3, 1)) + sm_dprintf("getla: fcntl(/dev/kmem, FD_CLOEXEC): %s\n", + sm_errstring(errno)); + (void) close(kmem); + kmem = -1; return -1; } - (void) fcntl(kmem, F_SETFD, FD_CLOEXEC); } if (lseek(kmem, (sysmp(MP_KERNADDR, MPKA_AVENRUN) & 0x7fffffff), SEEK_SET) == -1 || - read(kmem, (char *)avenrun, sizeof(avenrun)) < sizeof(avenrun)) + read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun)) { if (tTd(3, 1)) - dprintf("getla: lseek or read: %s\n", - errstring(errno)); + sm_dprintf("getla: lseek or read: %s\n", + sm_errstring(errno)); return -1; } if (tTd(3, 5)) { - dprintf("getla: avenrun = %ld", (long int) avenrun[0]); + sm_dprintf("getla: avenrun = %ld", (long int) avenrun[0]); if (tTd(3, 15)) - dprintf(", %ld, %ld", + sm_dprintf(", %ld, %ld", (long int) avenrun[1], (long int) avenrun[2]); - dprintf("\n"); + sm_dprintf("\n"); } if (tTd(3, 1)) - dprintf("getla: %d\n", + sm_dprintf("getla: %d\n", (int) (avenrun[0] + FSCALE/2) >> FSHIFT); return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT); @@ -2018,7 +1859,7 @@ int getla(void) # include <kstat.h> -static int +int getla() { static kstat_ctl_t *kc = NULL; @@ -2031,8 +1872,8 @@ getla() if (kc == NULL) { if (tTd(3, 1)) - dprintf("getla: kstat_open(): %s\n", - errstring(errno)); + sm_dprintf("getla: kstat_open(): %s\n", + sm_errstring(errno)); return -1; } if (ksp == NULL) @@ -2040,19 +1881,19 @@ getla() if (ksp == NULL) { if (tTd(3, 1)) - dprintf("getla: kstat_lookup(): %s\n", - errstring(errno)); + sm_dprintf("getla: kstat_lookup(): %s\n", + sm_errstring(errno)); return -1; } if (kstat_read(kc, ksp, NULL) < 0) { if (tTd(3, 1)) - dprintf("getla: kstat_read(): %s\n", - errstring(errno)); + sm_dprintf("getla: kstat_read(): %s\n", + sm_errstring(errno)); return -1; } ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min"); - la = ((double)ksn->value.ul + FSCALE/2) / FSCALE; + la = ((double) ksn->value.ul + FSCALE/2) / FSCALE; /* kstat_close(kc); /o do not close for fast access */ return la; } @@ -2073,7 +1914,7 @@ getla() # define _PATH_AVENRUN "/dev/table/avenrun" # endif /* ! _PATH_AVENRUN */ -static int +int getla() { static int afd = -1; @@ -2091,8 +1932,8 @@ getla() if (afd < 0) { sm_syslog(LOG_ERR, NOQID, - "can't open %s: %m", - _PATH_AVENRUN); + "can't open %s: %s", + _PATH_AVENRUN, sm_errstring(errno)); return -1; } } @@ -2100,10 +1941,10 @@ getla() r = read(afd, &avenrun, sizeof avenrun); if (tTd(3, 5)) - dprintf("getla: avenrun = %d\n", avenrun); + sm_dprintf("getla: avenrun = %d\n", avenrun); loadav = (int) (avenrun + FSCALE/2) >> FSHIFT; if (tTd(3, 1)) - dprintf("getla: %d\n", loadav); + sm_dprintf("getla: %d\n", loadav); return loadav; } @@ -2114,7 +1955,8 @@ struct rtentry; struct mbuf; # include <sys/table.h> -int getla() +int +getla() { int ave = 0; struct tbl_loadavg tab; @@ -2122,12 +1964,12 @@ int getla() if (table(TBL_LOADAVG, 0, &tab, 1, sizeof(tab)) == -1) { if (tTd(3, 1)) - dprintf("getla: table %s\n", errstring(errno)); + sm_dprintf("getla: table %s\n", sm_errstring(errno)); return -1; } if (tTd(3, 1)) - dprintf("getla: scale = %d\n", tab.tl_lscale); + sm_dprintf("getla: scale = %d\n", tab.tl_lscale); if (tab.tl_lscale) ave = ((tab.tl_avenrun.l[2] + (tab.tl_lscale/2)) / @@ -2136,7 +1978,7 @@ int getla() ave = (int) (tab.tl_avenrun.d[2] + 0.5); if (tTd(3, 1)) - dprintf("getla: %d\n", ave); + sm_dprintf("getla: %d\n", ave); return ave; } @@ -2145,7 +1987,7 @@ int getla() #if LA_TYPE == LA_PSET -static int +int getla() { double avenrun[3]; @@ -2154,12 +1996,12 @@ getla() sizeof(avenrun) / sizeof(avenrun[0])) < 0) { if (tTd(3, 1)) - dprintf("getla: pset_getloadavg failed: %s", - errstring(errno)); + sm_dprintf("getla: pset_getloadavg failed: %s", + sm_errstring(errno)); return -1; } if (tTd(3, 1)) - dprintf("getla: %d\n", (int) (avenrun[0] +0.5)); + sm_dprintf("getla: %d\n", (int) (avenrun[0] +0.5)); return ((int) (avenrun[0] + 0.5)); } @@ -2167,11 +2009,11 @@ getla() #if LA_TYPE == LA_ZERO -static int +int getla() { if (tTd(3, 1)) - dprintf("getla: ZERO\n"); + sm_dprintf("getla: ZERO\n"); return 0; } @@ -2202,7 +2044,7 @@ getla() /* Non Apollo stuff removed by Don Lewis 11/15/93 */ #ifndef lint -static char rcsid[] = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $"; +SM_UNUSED(static char rcsid[]) = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $"; #endif /* ! lint */ #ifdef apollo @@ -2211,61 +2053,57 @@ static char rcsid[] = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 pau /* ARGSUSED */ int getloadavg( call_data ) - caddr_t call_data; /* pointer to (double) return value */ + caddr_t call_data; /* pointer to (double) return value */ { - double *avenrun = (double *) call_data; - int i; - status_$t st; - long loadav[3]; - proc1_$get_loadav(loadav, &st); - *avenrun = loadav[0] / (double) (1 << 16); - return 0; + double *avenrun = (double *) call_data; + int i; + status_$t st; + long loadav[3]; + + proc1_$get_loadav(loadav, &st); + *avenrun = loadav[0] / (double) (1 << 16); + return 0; } #endif /* apollo */ -/* -** SM_GETLA -- get the current load average and set macro +/* +** SM_GETLA -- get the current load average ** ** Parameters: -** e -- the envelope for the load average macro. +** none ** ** Returns: -** The current load average as an integer. +** none ** ** Side Effects: -** Sets the load average macro ({load_avg}) if -** envelope e is not NULL. +** Set CurrentLA to the current load average. +** Set {load_avg} in GlobalMacros to the current load average. */ -int -sm_getla(e) - ENVELOPE *e; +void +sm_getla() { - register int la; - - la = getla(); - if (e != NULL) - { - char labuf[8]; + char labuf[8]; - snprintf(labuf, sizeof labuf, "%d", la); - define(macid("{load_avg}", NULL), newstr(labuf), e); - } - return la; + CurrentLA = getla(); + (void) sm_snprintf(labuf, sizeof labuf, "%d", CurrentLA); + macdefine(&GlobalMacros, A_TEMP, macid("{load_avg}"), labuf); } - -/* +/* ** SHOULDQUEUE -- should this message be queued or sent? ** ** Compares the message cost to the load average to decide. ** +** Note: Do NOT change this API! It is documented in op.me +** and theoretically the user can change this function... +** ** Parameters: ** pri -- the priority of the message in question. -** ct -- the message creation time. +** ct -- the message creation time (unused, but see above). ** ** Returns: -** TRUE -- if this message should be queued up for the +** true -- if this message should be queued up for the ** time being. -** FALSE -- if the load is low enough to send this message. +** false -- if the load is low enough to send this message. ** ** Side Effects: ** none. @@ -2280,65 +2118,114 @@ shouldqueue(pri, ct) bool rval; if (tTd(3, 30)) - dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ", + sm_dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ", CurrentLA, pri); if (CurrentLA < QueueLA) { if (tTd(3, 30)) - dprintf("FALSE (CurrentLA < QueueLA)\n"); - return FALSE; + sm_dprintf("false (CurrentLA < QueueLA)\n"); + return false; } -#if 0 /* this code is reported to cause oscillation around RefuseLA */ +# if 0 /* this code is reported to cause oscillation around RefuseLA */ if (CurrentLA >= RefuseLA && QueueLA < RefuseLA) { if (tTd(3, 30)) - dprintf("TRUE (CurrentLA >= RefuseLA)\n"); - return TRUE; + sm_dprintf("TRUE (CurrentLA >= RefuseLA)\n"); + return true; } -#endif /* 0 */ +# endif /* 0 */ rval = pri > (QueueFactor / (CurrentLA - QueueLA + 1)); if (tTd(3, 30)) - dprintf("%s (by calculation)\n", rval ? "TRUE" : "FALSE"); + sm_dprintf("%s (by calculation)\n", rval ? "true" : "false"); return rval; } -/* +/* ** REFUSECONNECTIONS -- decide if connections should be refused ** ** Parameters: ** name -- daemon name (for error messages only) ** e -- the current envelope. ** d -- number of daemon +** active -- was this daemon actually active? ** ** Returns: -** TRUE if incoming SMTP connections should be refused +** true if incoming SMTP connections should be refused ** (for now). -** FALSE if we should accept new work. +** false if we should accept new work. ** ** Side Effects: ** Sets process title when it is rejecting connections. */ bool -refuseconnections(name, e, d) +refuseconnections(name, e, d, active) char *name; ENVELOPE *e; int d; + bool active; { -#ifdef XLA + static time_t lastconn[MAXDAEMONS]; + static int conncnt[MAXDAEMONS]; + +#if XLA if (!xla_smtp_ok()) - return TRUE; + return true; #endif /* XLA */ - CurrentLA = sm_getla(NULL); + if (ConnRateThrottle > 0) + { + time_t now; + + now = curtime(); + if (active) + { + if (now != lastconn[d]) + { + lastconn[d] = now; + conncnt[d] = 1; + } + else if (conncnt[d]++ > ConnRateThrottle) + { +#define D_MSG_CRT "deferring connections on daemon %s: %d per second" + /* sleep to flatten out connection load */ + sm_setproctitle(true, e, D_MSG_CRT, + name, ConnRateThrottle); + if (LogLevel > 8) + sm_syslog(LOG_INFO, NOQID, D_MSG_CRT, + name, ConnRateThrottle); + (void) sleep(1); + } + } + else if (now != lastconn[d]) + conncnt[d] = 0; + } + + sm_getla(); if (RefuseLA > 0 && CurrentLA >= RefuseLA) { - sm_setproctitle(TRUE, e, "rejecting connections on daemon %s: load average: %d", - name, CurrentLA); - if (LogLevel >= 9) - sm_syslog(LOG_INFO, NOQID, - "rejecting connections on daemon %s: load average: %d", - name, CurrentLA); - return TRUE; +# define R_MSG_LA "rejecting connections on daemon %s: load average: %d" + sm_setproctitle(true, e, R_MSG_LA, name, CurrentLA); + if (LogLevel > 8) + sm_syslog(LOG_INFO, NOQID, R_MSG_LA, name, CurrentLA); + return true; + } + + if (DelayLA > 0 && CurrentLA >= DelayLA) + { + time_t now; + static time_t log_delay = (time_t) 0; + +# define MIN_DELAY_LOG 90 /* wait before logging this again */ +# define D_MSG_LA "delaying connections on daemon %s: load average=%d >= %d" + /* sleep to flatten out connection load */ + sm_setproctitle(true, e, D_MSG_LA, name, DelayLA); + if (LogLevel > 8 && (now = curtime()) > log_delay) + { + sm_syslog(LOG_INFO, NOQID, D_MSG_LA, + name, CurrentLA, DelayLA); + log_delay = now + MIN_DELAY_LOG; + } + (void) sleep(1); } if (MaxChildren > 0 && CurChildren >= MaxChildren) @@ -2346,19 +2233,18 @@ refuseconnections(name, e, d) proc_list_probe(); if (CurChildren >= MaxChildren) { - sm_setproctitle(TRUE, e, "rejecting connections on daemon %s: %d children, max %d", +#define R_MSG_CHILD "rejecting connections on daemon %s: %d children, max %d" + sm_setproctitle(true, e, R_MSG_CHILD, name, CurChildren, MaxChildren); - if (LogLevel >= 9) - sm_syslog(LOG_INFO, NOQID, - "rejecting connections on daemon %s: %d children, max %d", + if (LogLevel > 8) + sm_syslog(LOG_INFO, NOQID, R_MSG_CHILD, name, CurChildren, MaxChildren); - return TRUE; + return true; } } - - return FALSE; + return false; } -/* +/* ** SETPROCTITLE -- set process title for ps ** ** Parameters: @@ -2454,7 +2340,7 @@ initsetproctitle(argc, argv, envp) char **argv; char **envp; { - register int i, envpsize = 0; + register int i; extern char **environ; /* @@ -2463,7 +2349,7 @@ initsetproctitle(argc, argv, envp) */ for (i = 0; envp[i] != NULL; i++) - envpsize += strlen(envp[i]) + 1; + continue; environ = (char **) xalloc(sizeof (char *) * (i + 1)); for (i = 0; envp[i] != NULL; i++) environ[i] = newstr(envp[i]); @@ -2507,11 +2393,12 @@ setproctitle(fmt, va_alist) register int i; register char *p; SETPROC_STATIC char buf[SPT_BUFSIZE]; - VA_LOCAL_DECL + SM_VA_LOCAL_DECL # if SPT_TYPE == SPT_PSTAT union pstun pst; # endif /* SPT_TYPE == SPT_PSTAT */ # if SPT_TYPE == SPT_SCO + int j; off_t seek_off; static int kmem = -1; static pid_t kmempid = -1; @@ -2521,15 +2408,17 @@ setproctitle(fmt, va_alist) p = buf; /* print sendmail: heading for grep */ - (void) strlcpy(p, "sendmail: ", SPACELEFT(buf, p)); + (void) sm_strlcpy(p, "sendmail: ", SPACELEFT(buf, p)); p += strlen(p); /* print the argument string */ - VA_START(fmt); - (void) vsnprintf(p, SPACELEFT(buf, p), fmt, ap); - VA_END; + SM_VA_START(ap, fmt); + (void) sm_vsnprintf(p, SPACELEFT(buf, p), fmt, ap); + SM_VA_END(ap); - i = strlen(buf); + i = (int) strlen(buf); + if (i < 0) + return; # if SPT_TYPE == SPT_PSTAT pst.pst_command = buf; @@ -2543,15 +2432,21 @@ setproctitle(fmt, va_alist) sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf); # endif /* SPT_TYPE == SPT_SYSMIPS */ # if SPT_TYPE == SPT_SCO - if (kmem < 0 || kmempid != getpid()) + if (kmem < 0 || kmempid != CurrentPid) { if (kmem >= 0) (void) close(kmem); kmem = open(_PATH_KMEM, O_RDWR, 0); if (kmem < 0) return; - (void) fcntl(kmem, F_SETFD, FD_CLOEXEC); - kmempid = getpid(); + if ((j = fcntl(kmem, F_GETFD, 0)) < 0 || + fcntl(kmem, F_SETFD, j | FD_CLOEXEC) < 0) + { + (void) close(kmem); + kmem = -1; + return; + } + kmempid = CurrentPid; } buf[PSARGSZ - 1] = '\0'; seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u; @@ -2567,7 +2462,7 @@ setproctitle(fmt, va_alist) i = LastArgv - Argv[0] - 2; buf[i] = '\0'; } - (void) strlcpy(Argv[0], buf, i + 1); + (void) sm_strlcpy(Argv[0], buf, i + 1); p = &Argv[0][i]; while (p < LastArgv) *p++ = SPT_PADCHAR; @@ -2581,7 +2476,7 @@ setproctitle(fmt, va_alist) } #endif /* SPT_TYPE != SPT_BUILTIN */ -/* +/* ** SM_SETPROCTITLE -- set process task and set process title for ps ** ** Possibly set process status and call setproctitle() to @@ -2610,15 +2505,15 @@ sm_setproctitle(status, e, fmt, va_alist) #endif /* __STDC__ */ { char buf[SPT_BUFSIZE]; - VA_LOCAL_DECL + SM_VA_LOCAL_DECL /* print the argument string */ - VA_START(fmt); - (void) vsnprintf(buf, sizeof buf, fmt, ap); - VA_END; + SM_VA_START(ap, fmt); + (void) sm_vsnprintf(buf, sizeof buf, fmt, ap); + SM_VA_END(ap); if (status) - proc_list_set(getpid(), buf); + proc_list_set(CurrentPid, buf); if (ProcTitlePrefix != NULL) { @@ -2630,7 +2525,7 @@ sm_setproctitle(status, e, fmt, va_alist) else setproctitle("%s", buf); } -/* +/* ** WAITFOR -- wait for a particular process id. ** ** Parameters: @@ -2648,6 +2543,34 @@ int waitfor(pid) pid_t pid; { + int st; + pid_t i; + + do + { + errno = 0; + i = sm_wait(&st); + if (i > 0) + proc_list_drop(i, st, NULL); + } while ((i >= 0 || errno == EINTR) && i != pid); + if (i < 0) + return -1; + return st; +} +/* +** SM_WAIT -- wait +** +** Parameters: +** status -- pointer to status (return value) +** +** Returns: +** pid +*/ + +pid_t +sm_wait(status) + int *status; +{ # ifdef WAITUNION union wait st; # else /* WAITUNION */ @@ -2658,29 +2581,22 @@ waitfor(pid) int savesig; # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */ - do - { - errno = 0; # if defined(ISC_UNIX) || defined(_SCO_unix_) - savesig = releasesignal(SIGCHLD); + savesig = sm_releasesignal(SIGCHLD); # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */ - i = wait(&st); + i = wait(&st); # if defined(ISC_UNIX) || defined(_SCO_unix_) - if (savesig > 0) - blocksignal(SIGCHLD); + if (savesig > 0) + sm_blocksignal(SIGCHLD); # endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */ - if (i > 0) - (void) proc_list_drop(i); - } while ((i >= 0 || errno == EINTR) && i != pid); - if (i < 0) - return -1; # ifdef WAITUNION - return st.w_status; + *status = st.w_status; # else /* WAITUNION */ - return st; + *status = st; # endif /* WAITUNION */ + return i; } -/* +/* ** REAPCHILD -- pick up the body of my child, lest it become a zombie ** ** Parameters: @@ -2703,21 +2619,14 @@ SIGFUNC_DECL reapchild(sig) int sig; { + int m = 0; int save_errno = errno; int st; pid_t pid; # if HASWAITPID auto int status; int count; -# else /* HASWAITPID */ -# ifdef WNOHANG - union wait status; -# else /* WNOHANG */ - auto int status; -# endif /* WNOHANG */ -# endif /* HASWAITPID */ -# if HASWAITPID count = 0; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { @@ -2726,10 +2635,14 @@ reapchild(sig) break; # else /* HASWAITPID */ # ifdef WNOHANG + union wait status; + while ((pid = wait3(&status, WNOHANG, (struct rusage *) NULL)) > 0) { st = status.w_status; # else /* WNOHANG */ + auto int status; + /* ** Catch one zombie -- we will be re-invoked (we hope) if there ** are more. Unreliable signals probably break this, but this @@ -2743,170 +2656,14 @@ reapchild(sig) # endif /* WNOHANG */ # endif /* HASWAITPID */ /* Drop PID and check if it was a control socket child */ - if (proc_list_drop(pid) == PROC_CONTROL && - WIFEXITED(st)) - { - /* if so, see if we need to restart or shutdown */ - if (WEXITSTATUS(st) == EX_RESTART) - { - RestartRequest = "control socket"; - } - else if (WEXITSTATUS(st) == EX_SHUTDOWN) - { - /* emulate a SIGTERM shutdown */ - ShutdownRequest = "control socket"; - /* NOTREACHED */ - } - } + proc_list_drop(pid, st, NULL); + CurRunners -= m; /* Update */ } FIX_SYSV_SIGNAL(sig, reapchild); errno = save_errno; return SIGFUNC_RETURN; } -/* -** PUTENV -- emulation of putenv() in terms of setenv() -** -** Not needed on Posix-compliant systems. -** This doesn't have full Posix semantics, but it's good enough -** for sendmail. -** -** Parameter: -** env -- the environment to put. -** -** Returns: -** none. -*/ - -#if NEEDPUTENV - -# if NEEDPUTENV == 2 /* no setenv(3) call available */ - -int -putenv(str) - char *str; -{ - char **current; - int matchlen, envlen = 0; - char *tmp; - char **newenv; - static bool first = TRUE; - extern char **environ; - - /* - * find out how much of str to match when searching - * for a string to replace. - */ - if ((tmp = strchr(str, '=')) == NULL || tmp == str) - matchlen = strlen(str); - else - matchlen = (int) (tmp - str); - ++matchlen; - - /* - * Search for an existing string in the environment and find the - * length of environ. If found, replace and exit. - */ - for (current = environ; *current; current++) - { - ++envlen; - - if (strncmp(str, *current, matchlen) == 0) - { - /* found it, now insert the new version */ - *current = (char *)str; - return 0; - } - } - - /* - * There wasn't already a slot so add space for a new slot. - * If this is our first time through, use malloc(), else realloc(). - */ - if (first) - { - newenv = (char **) xalloc(sizeof(char *) * (envlen + 2)); - first = FALSE; - (void) memcpy(newenv, environ, sizeof(char *) * envlen); - } - else - { - newenv = (char **) xrealloc((char *)environ, - sizeof(char *) * (envlen + 2)); - } - - /* actually add in the new entry */ - environ = newenv; - environ[envlen] = (char *)str; - environ[envlen + 1] = NULL; - - return 0; -} - -# else /* NEEDPUTENV == 2 */ - -int -putenv(env) - char *env; -{ - char *p; - int l; - char nbuf[100]; - - p = strchr(env, '='); - if (p == NULL) - return 0; - l = p - env; - if (l > sizeof nbuf - 1) - l = sizeof nbuf - 1; - memmove(nbuf, env, l); - nbuf[l] = '\0'; - return setenv(nbuf, ++p, 1); -} - -# endif /* NEEDPUTENV == 2 */ -#endif /* NEEDPUTENV */ -/* -** UNSETENV -- remove a variable from the environment -** -** Not needed on newer systems. -** -** Parameters: -** name -- the string name of the environment variable to be -** deleted from the current environment. -** -** Returns: -** none. -** -** Globals: -** environ -- a pointer to the current environment. -** -** Side Effects: -** Modifies environ. -*/ - -#if !HASUNSETENV - -void -unsetenv(name) - char *name; -{ - extern char **environ; - register char **pp; - int len = strlen(name); - - for (pp = environ; *pp != NULL; pp++) - { - if (strncmp(name, *pp, len) == 0 && - ((*pp)[len] == '=' || (*pp)[len] == '\0')) - break; - } - - for (; *pp != NULL; pp++) - *pp = pp[1]; -} - -#endif /* !HASUNSETENV */ -/* +/* ** GETDTABLESIZE -- return number of file descriptors ** ** Only on non-BSD systems @@ -2945,7 +2702,7 @@ getdtsize() # endif /* _SC_OPEN_MAX */ # endif /* HASGETDTABLESIZE */ } -/* +/* ** UNAME -- get the UUCP name of this system. */ @@ -2955,16 +2712,18 @@ int uname(name) struct utsname *name; { - FILE *file; + SM_FILE_T *file; char *n; name->nodename[0] = '\0'; /* try /etc/whoami -- one line with the node name */ - if ((file = fopen("/etc/whoami", "r")) != NULL) + if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, "/etc/whoami", + SM_IO_RDONLY, NULL)) != NULL) { - (void) fgets(name->nodename, NODE_LENGTH + 1, file); - (void) fclose(file); + (void) sm_io_fgets(file, SM_TIME_DEFAULT, name->nodename, + NODE_LENGTH + 1); + (void) sm_io_close(file, SM_TIME_DEFAULT); n = strchr(name->nodename, '\n'); if (n != NULL) *n = '\0'; @@ -2973,17 +2732,19 @@ uname(name) } /* try /usr/include/whoami.h -- has a #define somewhere */ - if ((file = fopen("/usr/include/whoami.h", "r")) != NULL) + if ((file = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, + "/usr/include/whoami.h", SM_IO_RDONLY, NULL)) + != NULL) { char buf[MAXLINE]; - while (fgets(buf, MAXLINE, file) != NULL) + while (sm_io_fgets(file, SM_TIME_DEFAULT, buf, MAXLINE) != NULL) { - if (sscanf(buf, "#define sysname \"%*[^\"]\"", + if (sm_io_sscanf(buf, "#define sysname \"%*[^\"]\"", NODE_LENGTH, name->nodename) > 0) break; } - (void) fclose(file); + (void) sm_io_close(file, SM_TIME_DEFAULT); if (name->nodename[0] != '\0') return 0; } @@ -2996,7 +2757,8 @@ uname(name) /* try uuname -l to return local name */ if ((file = popen("uuname -l", "r")) != NULL) { - (void) fgets(name, NODE_LENGTH + 1, file); + (void) sm_io_fgets(file, SM_TIME_DEFAULT, name, + NODE_LENGTH + 1); (void) pclose(file); n = strchr(name, '\n'); if (n != NULL) @@ -3009,7 +2771,7 @@ uname(name) return -1; } #endif /* !HASUNAME */ -/* +/* ** INITGROUPS -- initialize groups ** ** Stub implementation for System V style systems @@ -3025,7 +2787,7 @@ initgroups(name, basegid) } #endif /* !HASINITGROUPS */ -/* +/* ** SETGROUPS -- set group list ** ** Stub implementation for systems that don't have group lists @@ -3042,7 +2804,7 @@ setgroups(ngroups, grouplist) } #endif /* ! NGROUPS_MAX */ -/* +/* ** SETSID -- set session id (for non-POSIX systems) */ @@ -3064,12 +2826,12 @@ setsid __P ((void)) # ifdef SYS5SETPGRP return setpgrp(); # else /* SYS5SETPGRP */ - return setpgid(0, getpid()); + return setpgid(0, CurrentPid); # endif /* SYS5SETPGRP */ } #endif /* !HASSETSID */ -/* +/* ** FSYNC -- dummy fsync */ @@ -3087,7 +2849,7 @@ fsync(fd) } #endif /* NEEDFSYNC */ -/* +/* ** DGUX_INET_ADDR -- inet_addr for DG/UX ** ** Data General DG/UX version of inet_addr returns a struct in_addr @@ -3110,11 +2872,11 @@ dgux_inet_addr(host) } #endif /* DGUX_5_4_2 */ -/* +/* ** GETOPT -- for old systems or systems with bogus implementations */ -#if NEEDGETOPT +#if !SM_CONF_GETOPT /* * Copyright (c) 1985 Regents of the University of California. @@ -3133,8 +2895,8 @@ static char sccsid[] = "@(#)getopt.c 4.3 (Berkeley) 3/9/86"; # endif /* defined(LIBC_SCCS) && !defined(lint) */ /* - * get option letter from argument vector - */ +** get option letter from argument vector +*/ # ifdef _CONVEX_SOURCE extern int optind, opterr, optopt; extern char *optarg; @@ -3147,8 +2909,12 @@ char *optarg = NULL; /* argument associated with option */ # define BADCH (int)'?' # define EMSG "" -# define tell(s) if (opterr) {fputs(*nargv,stderr);fputs(s,stderr); \ - fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);} +# define tell(s) if (opterr) \ + {sm_io_fputs(smioerr, SM_TIME_DEFAULT, *nargv); \ + (void) sm_io_fputs(smioerr, SM_TIME_DEFAULT, s); \ + (void) sm_io_putc(smioerr, SM_TIME_DEFAULT, optopt); \ + (void) sm_io_putc(smioerr, SM_TIME_DEFAULT, '\n'); \ + return BADCH;} int getopt(nargc,nargv,ostr) @@ -3193,52 +2959,11 @@ getopt(nargc,nargv,ostr) place = EMSG; ++optind; } - return(optopt); /* dump back option letter */ -} - -#endif /* NEEDGETOPT */ -/* -** VFPRINTF, VSPRINTF -- for old 4.3 BSD systems missing a real version -*/ - -#if NEEDVPRINTF - -# define MAXARG 16 - -vfprintf(fp, fmt, ap) - FILE *fp; - char *fmt; - char **ap; -{ - char *bp[MAXARG]; - int i = 0; - - while (*ap && i < MAXARG) - bp[i++] = *ap++; - fprintf(fp, fmt, bp[0], bp[1], bp[2], bp[3], - bp[4], bp[5], bp[6], bp[7], - bp[8], bp[9], bp[10], bp[11], - bp[12], bp[13], bp[14], bp[15]); -} - -vsprintf(s, fmt, ap) - char *s; - char *fmt; - char **ap; -{ - char *bp[MAXARG]; - int i = 0; - - while (*ap && i < MAXARG) - bp[i++] = *ap++; - sprintf(s, fmt, bp[0], bp[1], bp[2], bp[3], - bp[4], bp[5], bp[6], bp[7], - bp[8], bp[9], bp[10], bp[11], - bp[12], bp[13], bp[14], bp[15]); + return optopt; /* dump back option letter */ } -#endif /* NEEDVPRINTF */ -/* +#endif /* !SM_CONF_GETOPT */ +/* ** USERSHELLOK -- tell if a user's shell is ok for unrestricted use ** ** Parameters: @@ -3246,8 +2971,8 @@ vsprintf(s, fmt, ap) ** shell -- the user's shell from /etc/passwd ** ** Returns: -** TRUE -- if it is ok to use this for unrestricted access. -** FALSE -- if the shell is restricted. +** true -- if it is ok to use this for unrestricted access. +** false -- if the shell is restricted. */ #if !HASGETUSERSHELL @@ -3267,9 +2992,13 @@ vsprintf(s, fmt, ap) static char *DefaultUserShells[] = { "/bin/sh", /* standard shell */ +# ifdef MPE + "/SYS/PUB/CI", +# else /* MPE */ "/usr/bin/sh", "/bin/csh", /* C shell */ "/usr/bin/csh", +# endif /* MPE */ # ifdef __hpux # ifdef V4FS "/usr/bin/rsh", /* restricted Bourne shell */ @@ -3326,7 +3055,7 @@ usershellok(user, shell) if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') || ConfigLevel <= 1) - return TRUE; + return true; setusershell(); while ((p = getusershell()) != NULL) @@ -3338,12 +3067,12 @@ usershellok(user, shell) # if USEGETCONFATTR auto char *v; # endif /* USEGETCONFATTR */ - register FILE *shellf; + register SM_FILE_T *shellf; char buf[MAXLINE]; if (shell == NULL || shell[0] == '\0' || wordinclass(user, 't') || ConfigLevel <= 1) - return TRUE; + return true; # if USEGETCONFATTR /* @@ -3364,14 +3093,15 @@ usershellok(user, shell) while (*v != '\0') { if (strcmp(v, shell) == 0 || strcmp(v, WILDCARD_SHELL) == 0) - return TRUE; + return true; v += strlen(v) + 1; } - return FALSE; + return false; } # endif /* USEGETCONFATTR */ - shellf = fopen(_PATH_SHELLS, "r"); + shellf = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, _PATH_SHELLS, + SM_IO_RDONLY, NULL); if (shellf == NULL) { /* no /etc/shells; see if it is one of the std shells */ @@ -3380,17 +3110,17 @@ usershellok(user, shell) if (errno != ENOENT && LogLevel > 3) sm_syslog(LOG_ERR, NOQID, "usershellok: cannot open %s: %s", - _PATH_SHELLS, errstring(errno)); + _PATH_SHELLS, sm_errstring(errno)); for (d = DefaultUserShells; *d != NULL; d++) { if (strcmp(shell, *d) == 0) - return TRUE; + return true; } - return FALSE; + return false; } - while (fgets(buf, sizeof buf, shellf) != NULL) + while (sm_io_fgets(shellf, SM_TIME_DEFAULT, buf, sizeof buf) != NULL) { register char *p, *q; @@ -3405,15 +3135,15 @@ usershellok(user, shell) *p = '\0'; if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0) { - (void) fclose(shellf); - return TRUE; + (void) sm_io_close(shellf, SM_TIME_DEFAULT); + return true; } } - (void) fclose(shellf); - return FALSE; + (void) sm_io_close(shellf, SM_TIME_DEFAULT); + return false; # endif /* HASGETUSERSHELL */ } -/* +/* ** FREEDISKSPACE -- see how much free space is on the queue filesystem ** ** Only implemented if you have statfs. @@ -3432,40 +3162,46 @@ usershellok(user, shell) */ /* statfs types */ -#define SFS_NONE 0 /* no statfs implementation */ -#define SFS_USTAT 1 /* use ustat */ -#define SFS_4ARGS 2 /* use four-argument statfs call */ -#define SFS_VFS 3 /* use <sys/vfs.h> implementation */ -#define SFS_MOUNT 4 /* use <sys/mount.h> implementation */ -#define SFS_STATFS 5 /* use <sys/statfs.h> implementation */ -#define SFS_STATVFS 6 /* use <sys/statvfs.h> implementation */ - -#ifndef SFS_TYPE -# define SFS_TYPE SFS_NONE -#endif /* ! SFS_TYPE */ - -#if SFS_TYPE == SFS_USTAT -# include <ustat.h> -#endif /* SFS_TYPE == SFS_USTAT */ -#if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS -# include <sys/statfs.h> -#endif /* SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS */ -#if SFS_TYPE == SFS_VFS -# include <sys/vfs.h> -#endif /* SFS_TYPE == SFS_VFS */ -#if SFS_TYPE == SFS_MOUNT -# include <sys/mount.h> -#endif /* SFS_TYPE == SFS_MOUNT */ -#if SFS_TYPE == SFS_STATVFS -# include <sys/statvfs.h> -#endif /* SFS_TYPE == SFS_STATVFS */ +# define SFS_NONE 0 /* no statfs implementation */ +# define SFS_USTAT 1 /* use ustat */ +# define SFS_4ARGS 2 /* use four-argument statfs call */ +# define SFS_VFS 3 /* use <sys/vfs.h> implementation */ +# define SFS_MOUNT 4 /* use <sys/mount.h> implementation */ +# define SFS_STATFS 5 /* use <sys/statfs.h> implementation */ +# define SFS_STATVFS 6 /* use <sys/statvfs.h> implementation */ + +# ifndef SFS_TYPE +# define SFS_TYPE SFS_NONE +# endif /* ! SFS_TYPE */ + +# if SFS_TYPE == SFS_USTAT +# include <ustat.h> +# endif /* SFS_TYPE == SFS_USTAT */ +# if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS +# include <sys/statfs.h> +# endif /* SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS */ +# if SFS_TYPE == SFS_VFS +# include <sys/vfs.h> +# endif /* SFS_TYPE == SFS_VFS */ +# if SFS_TYPE == SFS_MOUNT +# include <sys/mount.h> +# endif /* SFS_TYPE == SFS_MOUNT */ +# if SFS_TYPE == SFS_STATVFS +# include <sys/statvfs.h> +# endif /* SFS_TYPE == SFS_STATVFS */ long freediskspace(dir, bsize) char *dir; long *bsize; { -# if SFS_TYPE != SFS_NONE +# if SFS_TYPE == SFS_NONE + if (bsize != NULL) + *bsize = 4096L; + + /* assume free space is plentiful */ + return (long) LONG_MAX; +# else /* SFS_TYPE == SFS_NONE */ # if SFS_TYPE == SFS_USTAT struct ustat fs; struct stat statbuf; @@ -3517,69 +3253,51 @@ freediskspace(dir, bsize) else return (long) fs.SFS_BAVAIL; } -# endif /* SFS_TYPE != SFS_NONE */ return -1; +# endif /* SFS_TYPE == SFS_NONE */ } -/* -** ENOUGHDISKSPACE -- is there enough free space on the queue fs? -** -** Only implemented if you have statfs. +/* +** ENOUGHDISKSPACE -- is there enough free space on the queue file systems? ** ** Parameters: ** msize -- the size to check against. If zero, we don't yet ** know how big the message will be, so just check for ** a "reasonable" amount. -** log -- log message? +** e -- envelope, or NULL -- controls logging ** ** Returns: -** TRUE if there is enough space. -** FALSE otherwise. +** true if in every queue group there is at least one +** queue directory whose file system contains enough free space. +** false otherwise. +** +** Side Effects: +** If there is not enough disk space and e != NULL +** then sm_syslog is called. */ bool -enoughdiskspace(msize, log) +enoughdiskspace(msize, e) long msize; - bool log; + ENVELOPE *e; { - long bfree; - long bsize; + int i; if (MinBlocksFree <= 0 && msize <= 0) { if (tTd(4, 80)) - dprintf("enoughdiskspace: no threshold\n"); - return TRUE; + sm_dprintf("enoughdiskspace: no threshold\n"); + return true; } - bfree = freediskspace(QueueDir, &bsize); - if (bfree >= 0) + filesys_update(); + for (i = 0; i < NumQueue; ++i) { - if (tTd(4, 80)) - dprintf("enoughdiskspace: bavail=%ld, need=%ld\n", - bfree, msize); - - /* convert msize to block count */ - msize = msize / bsize + 1; - if (MinBlocksFree >= 0) - msize += MinBlocksFree; - - if (bfree < msize) - { - if (log && LogLevel > 0) - sm_syslog(LOG_ALERT, CurEnv->e_id, - "low on space (have %ld, %s needs %ld in %s)", - bfree, - CurHostName == NULL ? "SMTP-DAEMON" : CurHostName, - msize, QueueDir); - return FALSE; - } + if (pickqdir(Queue[i], msize, e) < 0) + return false; } - else if (tTd(4, 80)) - dprintf("enoughdiskspace failure: min=%ld, need=%ld: %s\n", - MinBlocksFree, msize, errstring(errno)); - return TRUE; + return true; } -/* +/* ** TRANSIENTERROR -- tell if an error code indicates a transient failure ** ** This looks at an errno value and tells if this is likely to @@ -3589,8 +3307,8 @@ enoughdiskspace(msize, log) ** err -- the errno code to classify. ** ** Returns: -** TRUE if this is probably transient. -** FALSE otherwise. +** true if this is probably transient. +** false otherwise. */ bool @@ -3607,9 +3325,7 @@ transienterror(err) case ENFILE: /* Too many open files in system */ case EMFILE: /* Too many open files */ case ENOSPC: /* No space left on device */ -#ifdef ETIMEDOUT case ETIMEDOUT: /* Connection timed out */ -#endif /* ETIMEDOUT */ #ifdef ESTALE case ESTALE: /* Stale NFS file handle */ #endif /* ESTALE */ @@ -3680,13 +3396,13 @@ transienterror(err) case ENOLCK: /* No locks available */ #endif /* ENOLCK */ case E_SM_OPENTIMEOUT: /* PSEUDO: open timed out */ - return TRUE; + return true; } /* nope, must be permanent */ - return FALSE; + return false; } -/* +/* ** LOCKFILE -- lock a file using flock or (shudder) fcntl locking ** ** Parameters: @@ -3699,8 +3415,8 @@ transienterror(err) ** LOCK_UN -- unlock. ** ** Returns: -** TRUE if the lock was acquired. -** FALSE otherwise. +** true if the lock was acquired. +** false otherwise. */ bool @@ -3733,7 +3449,7 @@ lockfile(fd, filename, ext, type) action = F_SETLKW; if (tTd(55, 60)) - dprintf("lockfile(%s%s, action=%d, type=%d): ", + sm_dprintf("lockfile(%s%s, action=%d, type=%d): ", filename, ext, action, lfd.l_type); while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR) @@ -3741,13 +3457,13 @@ lockfile(fd, filename, ext, type) if (i >= 0) { if (tTd(55, 60)) - dprintf("SUCCESS\n"); - return TRUE; + sm_dprintf("SUCCESS\n"); + return true; } save_errno = errno; if (tTd(55, 60)) - dprintf("(%s) ", errstring(save_errno)); + sm_dprintf("(%s) ", sm_errstring(save_errno)); /* ** On SunOS, if you are testing using -oQ/tmp/mqueue or @@ -3761,8 +3477,8 @@ lockfile(fd, filename, ext, type) if (save_errno == EINVAL) { if (tTd(55, 60)) - dprintf("SUCCESS\n"); - return TRUE; + sm_dprintf("SUCCESS\n"); + return true; } if (!bitset(LOCK_NB, type) || @@ -3775,27 +3491,27 @@ lockfile(fd, filename, ext, type) # endif /* F_GETFL */ syserr("cannot lockf(%s%s, fd=%d, type=%o, omode=%o, euid=%d)", filename, ext, fd, type, omode, geteuid()); - dumpfd(fd, TRUE, TRUE); + dumpfd(fd, true, true); } # else /* !HASFLOCK */ if (ext == NULL) ext = ""; if (tTd(55, 60)) - dprintf("lockfile(%s%s, type=%o): ", filename, ext, type); + sm_dprintf("lockfile(%s%s, type=%o): ", filename, ext, type); while ((i = flock(fd, type)) < 0 && errno == EINTR) continue; if (i >= 0) { if (tTd(55, 60)) - dprintf("SUCCESS\n"); - return TRUE; + sm_dprintf("SUCCESS\n"); + return true; } save_errno = errno; if (tTd(55, 60)) - dprintf("(%s) ", errstring(save_errno)); + sm_dprintf("(%s) ", sm_errstring(save_errno)); if (!bitset(LOCK_NB, type) || save_errno != EWOULDBLOCK) { @@ -3806,15 +3522,15 @@ lockfile(fd, filename, ext, type) # endif /* F_GETFL */ syserr("cannot flock(%s%s, fd=%d, type=%o, omode=%o, euid=%d)", filename, ext, fd, type, omode, geteuid()); - dumpfd(fd, TRUE, TRUE); + dumpfd(fd, true, true); } # endif /* !HASFLOCK */ if (tTd(55, 60)) - dprintf("FAIL\n"); + sm_dprintf("FAIL\n"); errno = save_errno; - return FALSE; + return false; } -/* +/* ** CHOWNSAFE -- tell if chown is "safe" (executable only by root) ** ** Unfortunately, given that we can't predict other systems on which @@ -3862,9 +3578,9 @@ lockfile(fd, filename, ext, type) ** safedir -- set if the parent directory is safe. ** ** Returns: -** TRUE -- if the chown(2) operation is "safe" -- that is, +** true -- if the chown(2) operation is "safe" -- that is, ** only root can chown the file to an arbitrary user. -** FALSE -- if an arbitrary user can give away a file. +** false -- if an arbitrary user can give away a file. */ #ifndef IS_SAFE_CHOWN @@ -3882,7 +3598,7 @@ chownsafe(fd, safedir) /* give the system administrator a chance to override */ if (bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail)) - return TRUE; + return true; /* ** Some systems (e.g., SunOS) seem to have the call and the @@ -3897,11 +3613,11 @@ chownsafe(fd, safedir) # else /* SAFENFSPATHCONF */ return safedir && errno == 0 && rval IS_SAFE_CHOWN; # endif /* SAFENFSPATHCONF */ -# else /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \ */ +# else /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */ return bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail); -# endif /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && \ */ +# endif /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */ } -/* +/* ** RESETLIMITS -- reset system controlled resource limits ** ** This is to avoid denial-of-service attacks @@ -3944,40 +3660,15 @@ resetlimits() #endif /* HASSETRLIMIT */ errno = 0; } -/* -** GETCFNAME -- return the name of the .cf file. -** -** Some systems (e.g., NeXT) determine this dynamically. -*/ - -char * -getcfname() -{ - - if (ConfFile != NULL) - return ConfFile; -#if NETINFO - { - char *cflocation; - - cflocation = ni_propval("/locations", NULL, "sendmail", - "sendmail.cf", '\0'); - if (cflocation != NULL) - return cflocation; - } -#endif /* NETINFO */ - - return _PATH_SENDMAILCF; -} -/* +/* ** SETVENDOR -- process vendor code from V configuration line ** ** Parameters: ** vendor -- string representation of vendor. ** ** Returns: -** TRUE -- if ok. -** FALSE -- if vendor code could not be processed. +** true -- if ok. +** false -- if vendor code could not be processed. ** ** Side Effects: ** It is reasonable to set mode flags here to tweak @@ -3990,33 +3681,33 @@ bool setvendor(vendor) char *vendor; { - if (strcasecmp(vendor, "Berkeley") == 0) + if (sm_strcasecmp(vendor, "Berkeley") == 0) { VendorCode = VENDOR_BERKELEY; - return TRUE; + return true; } /* add vendor extensions here */ #ifdef SUN_EXTENSIONS - if (strcasecmp(vendor, "Sun") == 0) + if (sm_strcasecmp(vendor, "Sun") == 0) { VendorCode = VENDOR_SUN; - return TRUE; + return true; } #endif /* SUN_EXTENSIONS */ #if defined(VENDOR_NAME) && defined(VENDOR_CODE) - if (strcasecmp(vendor, VENDOR_NAME) == 0) + if (sm_strcasecmp(vendor, VENDOR_NAME) == 0) { VendorCode = VENDOR_CODE; - return TRUE; + return true; } #endif /* defined(VENDOR_NAME) && defined(VENDOR_CODE) */ - return FALSE; + return false; } -/* +/* ** GETVENDOR -- return vendor name based on vendor code ** ** Parameters: @@ -4043,26 +3734,26 @@ getvendor(vendorcode) switch (vendorcode) { - case VENDOR_BERKELEY: - return "Berkeley"; + case VENDOR_BERKELEY: + return "Berkeley"; - case VENDOR_SUN: - return "Sun"; + case VENDOR_SUN: + return "Sun"; - case VENDOR_HP: - return "HP"; + case VENDOR_HP: + return "HP"; - case VENDOR_IBM: - return "IBM"; + case VENDOR_IBM: + return "IBM"; - case VENDOR_SENDMAIL: - return "Sendmail"; + case VENDOR_SENDMAIL: + return "Sendmail"; - default: - return "Unknown"; + default: + return "Unknown"; } } -/* +/* ** VENDOR_PRE_DEFAULTS, VENDOR_POST_DEFAULTS -- set vendor-specific defaults ** ** Vendor_pre_defaults is called before reading the configuration @@ -4117,7 +3808,7 @@ vendor_post_defaults(e) sun_post_defaults(e); #endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */ } -/* +/* ** VENDOR_DAEMON_SETUP -- special vendor setup needed for daemon mode */ @@ -4132,11 +3823,11 @@ vendor_daemon_setup(e) if (getluid() != -1) { usrerr("Daemon cannot have LUID"); - finis(FALSE, EX_USAGE); + finis(false, true, EX_USAGE); } #endif /* SECUREWARE */ } -/* +/* ** VENDOR_SET_UID -- do setup for setting a user id ** ** This is called when we are still root. @@ -4165,7 +3856,7 @@ vendor_set_uid(uid) (void) setup_secure(uid); #endif /* SECUREWARE */ } -/* +/* ** VALIDATE_CONNECTION -- check connection for rationality ** ** If the connection is rejected, this routine should log an @@ -4189,61 +3880,69 @@ int allow_severity = LOG_INFO; int deny_severity = LOG_NOTICE; #endif /* TCPWRAPPERS */ -#if DAEMON char * validate_connection(sap, hostname, e) SOCKADDR *sap; char *hostname; ENVELOPE *e; { -# if TCPWRAPPERS +#if TCPWRAPPERS char *host; -# endif /* TCPWRAPPERS */ + char *addr; + extern int hosts_ctl(); +#endif /* TCPWRAPPERS */ if (tTd(48, 3)) - dprintf("validate_connection(%s, %s)\n", + sm_dprintf("validate_connection(%s, %s)\n", hostname, anynet_ntoa(sap)); if (rscheck("check_relay", hostname, anynet_ntoa(sap), - e, TRUE, TRUE, 4, NULL) != EX_OK) + e, true, true, 3, NULL, NOQID) != EX_OK) { static char reject[BUFSIZ*2]; extern char MsgBuf[]; if (tTd(48, 4)) - dprintf(" ... validate_connection: BAD (rscheck)\n"); + sm_dprintf(" ... validate_connection: BAD (rscheck)\n"); if (strlen(MsgBuf) >= 3) - (void) strlcpy(reject, MsgBuf, sizeof reject); + (void) sm_strlcpy(reject, MsgBuf, sizeof reject); else - (void) strlcpy(reject, "Access denied", sizeof reject); + (void) sm_strlcpy(reject, "Access denied", sizeof reject); return reject; } -# if TCPWRAPPERS +#if TCPWRAPPERS if (hostname[0] == '[' && hostname[strlen(hostname) - 1] == ']') host = "unknown"; else host = hostname; - if (!hosts_ctl("sendmail", host, anynet_ntoa(sap), STRING_UNKNOWN)) + addr = anynet_ntoa(sap); + +# if NETINET6 + /* TCP/Wrappers don't want the IPv6: protocol label */ + if (addr != NULL && sm_strncasecmp(addr, "IPv6:", 5) == 0) + addr += 5; +# endif /* NETINET6 */ + + if (!hosts_ctl("sendmail", host, addr, STRING_UNKNOWN)) { if (tTd(48, 4)) - dprintf(" ... validate_connection: BAD (tcpwrappers)\n"); - if (LogLevel >= 4) + sm_dprintf(" ... validate_connection: BAD (tcpwrappers)\n"); + if (LogLevel > 3) sm_syslog(LOG_NOTICE, e->e_id, - "tcpwrappers (%s, %s) rejection", - host, anynet_ntoa(sap)); + "tcpwrappers (%s, %s) rejection", + host, addr); return "Access denied"; } -# endif /* TCPWRAPPERS */ +#endif /* TCPWRAPPERS */ if (tTd(48, 4)) - dprintf(" ... validate_connection: OK\n"); + sm_dprintf(" ... validate_connection: OK\n"); return NULL; } -#endif /* DAEMON */ -/* +/* ** STRTOL -- convert string to long integer ** ** For systems that don't have it in the C library. @@ -4258,11 +3957,11 @@ static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93"; # endif /* defined(LIBC_SCCS) && !defined(lint) */ /* - * Convert a string to a long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ +** Convert a string to a long integer. +** +** Ignores `locale' stuff. Assumes that the upper and lower case +** alphabets and digits are each contiguous. +*/ long strtol(nptr, endptr, base) @@ -4277,10 +3976,10 @@ strtol(nptr, endptr, base) register int neg = 0, any, cutlim; /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ + ** Skip white space and pick up leading +/- sign if any. + ** If base is 0, allow 0x for hex and 0 for octal, else + ** assume decimal; if base is already 16, allow 0x. + */ do { c = *s++; } while (isspace(c)); @@ -4299,25 +3998,25 @@ strtol(nptr, endptr, base) base = c == '0' ? 8 : 10; /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for longs is - * [-2147483648..2147483647] and the input base is 10, - * cutoff will be set to 214748364 and cutlim to either - * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated - * a value > 214748364, or equal but the next digit is > 7 (or 8), - * the number is too big, and we will return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; - cutlim = cutoff % (unsigned long)base; - cutoff /= (unsigned long)base; + ** Compute the cutoff value between legal numbers and illegal + ** numbers. That is the largest legal value, divided by the + ** base. An input number that is greater than this value, if + ** followed by a legal input character, is too big. One that + ** is equal to this value may be valid or not; the limit + ** between valid and invalid numbers is then based on the last + ** digit. For instance, if the range for longs is + ** [-2147483648..2147483647] and the input base is 10, + ** cutoff will be set to 214748364 and cutlim to either + ** 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated + ** a value > 214748364, or equal but the next digit is > 7 (or 8), + ** the number is too big, and we will return a range error. + ** + ** Set any if any `digits' consumed; make it negative to indicate + ** overflow. + */ + cutoff = neg ? -(unsigned long) LONG_MIN : LONG_MAX; + cutlim = cutoff % (unsigned long) base; + cutoff /= (unsigned long) base; for (acc = 0, any = 0;; c = *s++) { if (isdigit(c)) c -= '0'; @@ -4346,7 +4045,7 @@ strtol(nptr, endptr, base) } #endif /* NEEDSTRTOL */ -/* +/* ** STRSTR -- find first substring in string ** ** Parameters: @@ -4383,7 +4082,7 @@ strstr(big, little) } #endif /* NEEDSTRSTR */ -/* +/* ** SM_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX ** ** Some operating systems have wierd problems with the gethostbyXXX @@ -4416,7 +4115,7 @@ getipnodebyname(name, family, flags, err) int flags; int *err; { - bool resv6 = TRUE; + bool resv6 = true; struct hostent *h; if (family == AF_INET6) @@ -4427,9 +4126,9 @@ getipnodebyname(name, family, flags, err) } SM_SET_H_ERRNO(0); h = gethostbyname(name); - *err = h_errno; - if (family == AF_INET6 && !resv6) + if (!resv6) _res.options &= ~RES_USE_INET6; + *err = h_errno; return h; } @@ -4448,7 +4147,6 @@ getipnodebyaddr(addr, len, family, err) return h; } -# if _FFR_FREEHOSTENT void freehostent(h) struct hostent *h; @@ -4460,8 +4158,7 @@ freehostent(h) return; } -# endif /* _FFR_FREEHOSTENT */ -#endif /* NEEDSGETIPNODE && NETINET6 */ +#endif /* NETINET6 && NEEDSGETIPNODE */ struct hostent * sm_gethostbyname(name, family) @@ -4477,14 +4174,14 @@ sm_gethostbyname(name, family) extern struct hostent *_switch_gethostbyname_r(); if (tTd(61, 10)) - dprintf("_switch_gethostbyname_r(%s)... ", name); + sm_dprintf("_switch_gethostbyname_r(%s)... ", name); h = _switch_gethostbyname_r(name, &hp, buf, sizeof(buf), &h_errno); save_errno = errno; # else /* SOLARIS == 20300 || SOLARIS == 203 */ extern struct hostent *__switch_gethostbyname(); if (tTd(61, 10)) - dprintf("__switch_gethostbyname(%s)... ", name); + sm_dprintf("__switch_gethostbyname(%s)... ", name); h = __switch_gethostbyname(name); save_errno = errno; # endif /* SOLARIS == 20300 || SOLARIS == 203 */ @@ -4499,7 +4196,7 @@ sm_gethostbyname(name, family) char hbuf[MAXNAME]; if (tTd(61, 10)) - dprintf("sm_gethostbyname(%s, %d)... ", name, family); + sm_dprintf("sm_gethostbyname(%s, %d)... ", name, family); # if NETINET6 # if ADDRCONFIG_IS_BROKEN @@ -4515,7 +4212,7 @@ sm_gethostbyname(name, family) if (h == NULL) { if (tTd(61, 10)) - dprintf("failure\n"); + sm_dprintf("failure\n"); nmaps = switch_map_find("hosts", maptype, mapreturn); while (--nmaps >= 0) @@ -4528,19 +4225,19 @@ sm_gethostbyname(name, family) if (nmaps >= 0) { /* try short name */ - if (strlen(name) > (SIZE_T) sizeof hbuf - 1) + if (strlen(name) > sizeof hbuf - 1) { errno = save_errno; return NULL; } - (void) strlcpy(hbuf, name, sizeof hbuf); + (void) sm_strlcpy(hbuf, name, sizeof hbuf); (void) shorten_hostname(hbuf); /* if it hasn't been shortened, there's no point */ if (strcmp(hbuf, name) != 0) { if (tTd(61, 10)) - dprintf("sm_gethostbyname(%s, %d)... ", + sm_dprintf("sm_gethostbyname(%s, %d)... ", hbuf, family); # if NETINET6 @@ -4558,10 +4255,10 @@ sm_gethostbyname(name, family) if (tTd(61, 10)) { if (h == NULL) - dprintf("failure\n"); + sm_dprintf("failure\n"); else { - dprintf("%s\n", h->h_name); + sm_dprintf("%s\n", h->h_name); if (tTd(61, 11)) { #if NETINET6 @@ -4570,12 +4267,12 @@ sm_gethostbyname(name, family) #else /* NETINET6 */ struct in_addr ia; #endif /* NETINET6 */ - int i; + size_t i; if (h->h_aliases != NULL) for (i = 0; h->h_aliases[i] != NULL; i++) - dprintf("\talias: %s\n", + sm_dprintf("\talias: %s\n", h->h_aliases[i]); for (i = 0; h->h_addr_list[i] != NULL; i++) { @@ -4592,7 +4289,7 @@ sm_gethostbyname(name, family) addr = (char *) inet_ntoa(ia); #endif /* NETINET6 */ if (addr != NULL) - dprintf("\taddr: %s\n", addr); + sm_dprintf("\taddr: %s\n", addr); } } } @@ -4650,37 +4347,36 @@ sm_gethostbyaddr(addr, len, type) #endif /* (SOLARIS > 10000 && SOLARIS < 20400) || (defined(SOLARIS) && SOLARIS < 204) */ return hp; } -/* +/* ** SM_GETPW{NAM,UID} -- wrapper for getpwnam and getpwuid */ - struct passwd * sm_getpwnam(user) char *user; { -# ifdef _AIX4 +#ifdef _AIX4 extern struct passwd *_getpwnam_shadow(const char *, const int); return _getpwnam_shadow(user, 0); -# else /* _AIX4 */ +#else /* _AIX4 */ return getpwnam(user); -# endif /* _AIX4 */ +#endif /* _AIX4 */ } struct passwd * sm_getpwuid(uid) UID_T uid; { -# if defined(_AIX4) && 0 +#if defined(_AIX4) && 0 extern struct passwd *_getpwuid_shadow(const int, const int); return _getpwuid_shadow(uid,0); -# else /* defined(_AIX4) && 0 */ +#else /* defined(_AIX4) && 0 */ return getpwuid(uid); -# endif /* defined(_AIX4) && 0 */ +#endif /* defined(_AIX4) && 0 */ } -/* +/* ** SECUREWARE_SETUP_SECURE -- Convex SecureWare setup ** ** Set up the trusted computing environment for C2 level security @@ -4715,34 +4411,38 @@ secureware_setup_secure(uid) switch (rc) { case SSI_NO_PRPW_ENTRY: - syserr("No protected passwd entry, uid = %d", uid); + syserr("No protected passwd entry, uid = %d", + (int) uid); break; case SSI_LOCKED: - syserr("Account has been disabled, uid = %d", uid); + syserr("Account has been disabled, uid = %d", + (int) uid); break; case SSI_RETIRED: - syserr("Account has been retired, uid = %d", uid); + syserr("Account has been retired, uid = %d", + (int) uid); break; case SSI_BAD_SET_LUID: - syserr("Could not set LUID, uid = %d", uid); + syserr("Could not set LUID, uid = %d", (int) uid); break; case SSI_BAD_SET_PRIVS: - syserr("Could not set kernel privs, uid = %d", uid); + syserr("Could not set kernel privs, uid = %d", + (int) uid); default: syserr("Unknown return code (%d) from set_secure_info(%d)", - rc, uid); + rc, (int) uid); break; } - finis(FALSE, EX_NOPERM); + finis(false, true, EX_NOPERM); } } #endif /* SECUREWARE */ -/* +/* ** ADD_HOSTNAMES -- Add a hostname to class 'w' based on IP address ** ** Add hostnames to class 'w' based on the IP address read from @@ -4767,28 +4467,28 @@ add_hostnames(sa) switch (sa->sa.sa_family) { #if NETINET - case AF_INET: - hp = sm_gethostbyaddr((char *) &sa->sin.sin_addr, - sizeof(sa->sin.sin_addr), - sa->sa.sa_family); - break; + case AF_INET: + hp = sm_gethostbyaddr((char *) &sa->sin.sin_addr, + sizeof(sa->sin.sin_addr), + sa->sa.sa_family); + break; #endif /* NETINET */ #if NETINET6 - case AF_INET6: - hp = sm_gethostbyaddr((char *) &sa->sin6.sin6_addr, - sizeof(sa->sin6.sin6_addr), - sa->sa.sa_family); - break; + case AF_INET6: + hp = sm_gethostbyaddr((char *) &sa->sin6.sin6_addr, + sizeof(sa->sin6.sin6_addr), + sa->sa.sa_family); + break; #endif /* NETINET6 */ - default: - /* Give warning about unsupported family */ - if (LogLevel > 3) - sm_syslog(LOG_WARNING, NOQID, - "Unsupported address family %d: %.100s", - sa->sa.sa_family, anynet_ntoa(sa)); - return -1; + default: + /* Give warning about unsupported family */ + if (LogLevel > 3) + sm_syslog(LOG_WARNING, NOQID, + "Unsupported address family %d: %.100s", + sa->sa.sa_family, anynet_ntoa(sa)); + return -1; } if (hp == NULL) @@ -4800,16 +4500,16 @@ add_hostnames(sa) !(sa->sa.sa_family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr)) && #endif /* NETINET6 */ - TRUE) + true) sm_syslog(LOG_WARNING, NOQID, - "gethostbyaddr(%.100s) failed: %d\n", - anynet_ntoa(sa), + "gethostbyaddr(%.100s) failed: %d", + anynet_ntoa(sa), #if NAMED_BIND - h_errno + h_errno #else /* NAMED_BIND */ - -1 + -1 #endif /* NAMED_BIND */ - ); + ); errno = save_errno; return -1; } @@ -4819,16 +4519,16 @@ add_hostnames(sa) { setclass('w', (char *) hp->h_name); if (tTd(0, 4)) - dprintf("\ta.k.a.: %s\n", hp->h_name); + sm_dprintf("\ta.k.a.: %s\n", hp->h_name); - if (snprintf(hnb, sizeof hnb, "[%s]", hp->h_name) < sizeof hnb + if (sm_snprintf(hnb, sizeof hnb, "[%s]", hp->h_name) < sizeof hnb && !wordinclass((char *) hnb, 'w')) setclass('w', hnb); } else { if (tTd(0, 43)) - dprintf("\ta.k.a.: %s (already in $=w)\n", hp->h_name); + sm_dprintf("\ta.k.a.: %s (already in $=w)\n", hp->h_name); } /* save all it aliases name */ @@ -4838,8 +4538,8 @@ add_hostnames(sa) { setclass('w', *ha); if (tTd(0, 4)) - dprintf("\ta.k.a.: %s\n", *ha); - if (snprintf(hnb, sizeof hnb, + sm_dprintf("\ta.k.a.: %s\n", *ha); + if (sm_snprintf(hnb, sizeof hnb, "[%s]", *ha) < sizeof hnb && !wordinclass((char *) hnb, 'w')) setclass('w', hnb); @@ -4847,16 +4547,16 @@ add_hostnames(sa) else { if (tTd(0, 43)) - dprintf("\ta.k.a.: %s (already in $=w)\n", + sm_dprintf("\ta.k.a.: %s (already in $=w)\n", *ha); } } -#if _FFR_FREEHOSTENT && NETINET6 +#if NETINET6 freehostent(hp); -#endif /* _FFR_FREEHOSTENT && NETINET6 */ +#endif /* NETINET6 */ return 0; } -/* +/* ** LOAD_IF_NAMES -- load interface-specific names into $=w ** ** Parameters: @@ -4888,36 +4588,63 @@ struct mbuf; void load_if_names() { -#if NETINET6 && defined(SIOCGLIFCONF) +# if NETINET6 && defined(SIOCGLIFCONF) +# ifdef __hpux + + /* + ** Unfortunately, HP has changed all of the structures, + ** making life difficult for implementors. + */ + +# define lifconf if_laddrconf +# define lifc_len iflc_len +# define lifc_buf iflc_buf +# define lifreq if_laddrreq +# define lifr_addr iflr_addr +# define lifr_name iflr_name +# define lifr_flags iflr_flags +# define ss_family sa_family +# undef SIOCGLIFNUM +# endif /* __hpux */ + int s; int i; + size_t len; + int numifs; + char *buf; struct lifconf lifc; +# ifdef SIOCGLIFNUM struct lifnum lifn; - int numifs; +# endif /* SIOCGLIFNUM */ s = socket(InetMode, SOCK_DGRAM, 0); if (s == -1) return; /* get the list of known IP address from the kernel */ -# ifdef SIOCGLIFNUM +# ifdef __hpux + i = ioctl(s, SIOCGIFNUM, (char *) &numifs); +# endif /* __hpux */ +# ifdef SIOCGLIFNUM lifn.lifn_family = AF_UNSPEC; lifn.lifn_flags = 0; - if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) + i = ioctl(s, SIOCGLIFNUM, (char *)&lifn); + numifs = lifn.lifn_count; +# endif /* SIOCGLIFNUM */ + +# if defined(__hpux) || defined(SIOCGLIFNUM) + if (i < 0) { /* can't get number of interfaces -- fall back */ if (tTd(0, 4)) - dprintf("SIOCGLIFNUM failed: %s\n", errstring(errno)); + sm_dprintf("SIOCGLIFNUM failed: %s\n", + sm_errstring(errno)); numifs = -1; } - else - { - numifs = lifn.lifn_count; - if (tTd(0, 42)) - dprintf("system has %d interfaces\n", numifs); - } + else if (tTd(0, 42)) + sm_dprintf("system has %d interfaces\n", numifs); if (numifs < 0) -# endif /* SIOCGLIFNUM */ +# endif /* defined(__hpux) || defined(SIOCGLIFNUM) */ numifs = MAXINTERFACES; if (numifs <= 0) @@ -4925,37 +4652,43 @@ load_if_names() (void) close(s); return; } - lifc.lifc_len = numifs * sizeof (struct lifreq); - lifc.lifc_buf = xalloc(lifc.lifc_len); + + len = lifc.lifc_len = numifs * sizeof (struct lifreq); + buf = lifc.lifc_buf = xalloc(lifc.lifc_len); +# ifndef __hpux lifc.lifc_family = AF_UNSPEC; lifc.lifc_flags = 0; +# endif /* __hpux */ if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) { if (tTd(0, 4)) - dprintf("SIOCGLIFCONF failed: %s\n", errstring(errno)); + sm_dprintf("SIOCGLIFCONF failed: %s\n", + sm_errstring(errno)); (void) close(s); - sm_free(lifc.lifc_buf); + sm_free(buf); return; } /* scan the list of IP address */ if (tTd(0, 40)) - dprintf("scanning for interface specific names, lifc_len=%d\n", - lifc.lifc_len); + sm_dprintf("scanning for interface specific names, lifc_len=%ld\n", + (long) len); - for (i = 0; i < lifc.lifc_len; ) + for (i = 0; i < len && i >= 0; ) { - struct lifreq *ifr = (struct lifreq *)&lifc.lifc_buf[i]; + int flags; + struct lifreq *ifr = (struct lifreq *)&buf[i]; SOCKADDR *sa = (SOCKADDR *) &ifr->lifr_addr; + int af = ifr->lifr_addr.ss_family; char *addr; + char *name; struct in6_addr ia6; struct in_addr ia; -# ifdef SIOCGLIFFLAGS +# ifdef SIOCGLIFFLAGS struct lifreq ifrf; -# endif /* SIOCGLIFFLAGS */ +# endif /* SIOCGLIFFLAGS */ char ip_addr[256]; char buf6[INET6_ADDRSTRLEN]; - int af = ifr->lifr_addr.ss_family; /* ** We must close and recreate the socket each time @@ -4968,7 +4701,7 @@ load_if_names() s = socket(af, SOCK_DGRAM, 0); if (s == -1) { - sm_free(lifc.lifc_buf); + sm_free(buf); /* XXX */ return; } @@ -4977,40 +4710,43 @@ load_if_names() ** don't try to use it. */ - if ((lifc.lifc_len - i) < sizeof *ifr) + if ((len - i) < sizeof *ifr) break; -# ifdef BSD4_4_SOCKADDR +# ifdef BSD4_4_SOCKADDR if (sa->sa.sa_len > sizeof ifr->lifr_addr) i += sizeof ifr->lifr_name + sa->sa.sa_len; else -# endif /* BSD4_4_SOCKADDR */ +# endif /* BSD4_4_SOCKADDR */ i += sizeof *ifr; if (tTd(0, 20)) - dprintf("%s\n", anynet_ntoa(sa)); + sm_dprintf("%s\n", anynet_ntoa(sa)); if (af != AF_INET && af != AF_INET6) continue; -# ifdef SIOCGLIFFLAGS +# ifdef SIOCGLIFFLAGS memset(&ifrf, '\0', sizeof(struct lifreq)); - (void) strlcpy(ifrf.lifr_name, ifr->lifr_name, - sizeof(ifrf.lifr_name)); + (void) sm_strlcpy(ifrf.lifr_name, ifr->lifr_name, + sizeof(ifrf.lifr_name)); if (ioctl(s, SIOCGLIFFLAGS, (char *) &ifrf) < 0) { if (tTd(0, 4)) - dprintf("SIOCGLIFFLAGS failed: %s\n", - errstring(errno)); + sm_dprintf("SIOCGLIFFLAGS failed: %s\n", + sm_errstring(errno)); continue; } - else if (tTd(0, 41)) - dprintf("\tflags: %lx\n", - (unsigned long)ifrf.lifr_flags); - if (!bitset(IFF_UP, ifrf.lifr_flags)) + name = ifr->lifr_name; + flags = ifrf.lifr_flags; + + if (tTd(0, 41)) + sm_dprintf("\tflags: %lx\n", (unsigned long) flags); + + if (!bitset(IFF_UP, flags)) continue; -# endif /* SIOCGLIFFLAGS */ +# endif /* SIOCGLIFFLAGS */ ip_addr[0] = '\0'; @@ -5037,17 +4773,17 @@ load_if_names() { addr = anynet_ntop(&ia6, buf6, sizeof buf6); message("WARNING: interface %s is UP with %s address", - ifr->lifr_name, - addr == NULL ? "(NULL)" : addr); + name, addr == NULL ? "(NULL)" : addr); continue; } /* save IP address in text from */ addr = anynet_ntop(&ia6, buf6, sizeof buf6); if (addr != NULL) - (void) snprintf(ip_addr, sizeof ip_addr, - "[%.*s]", - (int) sizeof ip_addr - 3, addr); + (void) sm_snprintf(ip_addr, sizeof ip_addr, + "[%.*s]", + (int) sizeof ip_addr - 3, + addr); break; case AF_INET: @@ -5056,12 +4792,12 @@ load_if_names() ia.s_addr == INADDR_NONE) { message("WARNING: interface %s is UP with %s address", - ifr->lifr_name, inet_ntoa(ia)); + name, inet_ntoa(ia)); continue; } /* save IP address in text from */ - (void) snprintf(ip_addr, sizeof ip_addr, "[%.*s]", + (void) sm_snprintf(ip_addr, sizeof ip_addr, "[%.*s]", (int) sizeof ip_addr - 3, inet_ntoa(ia)); break; } @@ -5073,20 +4809,21 @@ load_if_names() { setclass('w', ip_addr); if (tTd(0, 4)) - dprintf("\ta.k.a.: %s\n", ip_addr); + sm_dprintf("\ta.k.a.: %s\n", ip_addr); } -# ifdef SIOCGLIFFLAGS +# ifdef SIOCGLIFFLAGS /* skip "loopback" interface "lo" */ - if (bitset(IFF_LOOPBACK, ifrf.lifr_flags)) + if (DontProbeInterfaces == DPI_SKIPLOOPBACK && + bitset(IFF_LOOPBACK, flags)) continue; -# endif /* SIOCGLIFFLAGS */ +# endif /* SIOCGLIFFLAGS */ (void) add_hostnames(sa); } - sm_free(lifc.lifc_buf); + sm_free(buf); /* XXX */ (void) close(s); -#else /* NETINET6 && defined(SIOCGLIFCONF) */ -# if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN +# else /* NETINET6 && defined(SIOCGLIFCONF) */ +# if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN int s; int i; struct ifconf ifc; @@ -5097,18 +4834,19 @@ load_if_names() return; /* get the list of known IP address from the kernel */ -# if defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN +# if defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN if (ioctl(s, SIOCGIFNUM, (char *) &numifs) < 0) { /* can't get number of interfaces -- fall back */ if (tTd(0, 4)) - dprintf("SIOCGIFNUM failed: %s\n", errstring(errno)); + sm_dprintf("SIOCGIFNUM failed: %s\n", + sm_errstring(errno)); numifs = -1; } else if (tTd(0, 42)) - dprintf("system has %d interfaces\n", numifs); + sm_dprintf("system has %d interfaces\n", numifs); if (numifs < 0) -# endif /* defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN */ +# endif /* defined(SIOCGIFNUM) && !SIOCGIFNUM_IS_BROKEN */ numifs = MAXINTERFACES; if (numifs <= 0) @@ -5121,18 +4859,18 @@ load_if_names() if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { if (tTd(0, 4)) - dprintf("SIOCGIFCONF failed: %s\n", errstring(errno)); + sm_dprintf("SIOCGIFCONF failed: %s\n", + sm_errstring(errno)); (void) close(s); - sm_free(ifc.ifc_buf); return; } /* scan the list of IP address */ if (tTd(0, 40)) - dprintf("scanning for interface specific names, ifc_len=%d\n", + sm_dprintf("scanning for interface specific names, ifc_len=%d\n", ifc.ifc_len); - for (i = 0; i < ifc.ifc_len; ) + for (i = 0; i < ifc.ifc_len && i >= 0; ) { int af; struct ifreq *ifr = (struct ifreq *) &ifc.ifc_buf[i]; @@ -5166,7 +4904,7 @@ load_if_names() i += sizeof *ifr; if (tTd(0, 20)) - dprintf("%s\n", anynet_ntoa(sa)); + sm_dprintf("%s\n", anynet_ntoa(sa)); af = ifr->ifr_addr.sa_family; if (af != AF_INET @@ -5178,11 +4916,11 @@ load_if_names() # ifdef SIOCGIFFLAGS memset(&ifrf, '\0', sizeof(struct ifreq)); - (void) strlcpy(ifrf.ifr_name, ifr->ifr_name, + (void) sm_strlcpy(ifrf.ifr_name, ifr->ifr_name, sizeof(ifrf.ifr_name)); (void) ioctl(s, SIOCGIFFLAGS, (char *) &ifrf); if (tTd(0, 41)) - dprintf("\tflags: %lx\n", + sm_dprintf("\tflags: %lx\n", (unsigned long) ifrf.ifr_flags); # define IFRFREF ifrf # else /* SIOCGIFFLAGS */ @@ -5208,7 +4946,7 @@ load_if_names() } /* save IP address in text from */ - (void) snprintf(ip_addr, sizeof ip_addr, "[%.*s]", + (void) sm_snprintf(ip_addr, sizeof ip_addr, "[%.*s]", (int) sizeof ip_addr - 3, inet_ntoa(ia)); break; @@ -5242,9 +4980,10 @@ load_if_names() /* save IP address in text from */ addr = anynet_ntop(&ia6, buf6, sizeof buf6); if (addr != NULL) - (void) snprintf(ip_addr, sizeof ip_addr, - "[%.*s]", - (int) sizeof ip_addr - 3, addr); + (void) sm_snprintf(ip_addr, sizeof ip_addr, + "[%.*s]", + (int) sizeof ip_addr - 3, + addr); break; # endif /* NETINET6 */ @@ -5257,30 +4996,31 @@ load_if_names() { setclass('w', ip_addr); if (tTd(0, 4)) - dprintf("\ta.k.a.: %s\n", ip_addr); + sm_dprintf("\ta.k.a.: %s\n", ip_addr); } /* skip "loopback" interface "lo" */ - if (bitset(IFF_LOOPBACK, IFRFREF.ifr_flags)) + if (DontProbeInterfaces == DPI_SKIPLOOPBACK && + bitset(IFF_LOOPBACK, IFRFREF.ifr_flags)) continue; (void) add_hostnames(sa); } - sm_free(ifc.ifc_buf); + sm_free(ifc.ifc_buf); /* XXX */ (void) close(s); -# undef IFRFREF -# endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */ -#endif /* NETINET6 && defined(SIOCGLIFCONF) */ +# undef IFRFREF +# endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */ +# endif /* NETINET6 && defined(SIOCGLIFCONF) */ } -/* +/* ** ISLOOPBACK -- is socket address in the loopback net? ** ** Parameters: ** sa -- socket address. ** ** Returns: -** TRUE -- is socket address in the loopback net? -** FALSE -- otherwise +** true -- is socket address in the loopback net? +** false -- otherwise ** */ @@ -5290,16 +5030,16 @@ isloopback(sa) { #if NETINET6 if (IN6_IS_ADDR_LOOPBACK(&sa.sin6.sin6_addr)) - return TRUE; + return true; #else /* NETINET6 */ /* XXX how to correctly extract IN_LOOPBACKNET part? */ if (((ntohl(sa.sin.sin_addr.s_addr) & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) - return TRUE; + return true; #endif /* NETINET6 */ - return FALSE; + return false; } -/* +/* ** GET_NUM_PROCS_ONLINE -- return the number of processors currently online ** ** Parameters: @@ -5323,7 +5063,7 @@ get_num_procs_online() mib[1] = HW_NCPU; sz = (size_t) sizeof nproc; (void) sysctl(mib, 2, &nproc, &sz, NULL, 0); -# endif /* defined(CTL_HW) && defined(HW_NCPUS) */ +# endif /* defined(CTL_HW) && defined(HW_NCPU) */ #else /* USESYSCTL */ # ifdef _SC_NPROCESSORS_ONLN nproc = (int) sysconf(_SC_NPROCESSORS_ONLN); @@ -5342,7 +5082,7 @@ get_num_procs_online() nproc = 1; return nproc; } -/* +/* ** SEED_RANDOM -- seed the random number generator ** ** Parameters: @@ -5361,7 +5101,7 @@ seed_random() long seed; struct timeval t; - seed = (long) getpid(); + seed = (long) CurrentPid; if (gettimeofday(&t, NULL) >= 0) seed += t.tv_sec + t.tv_usec; @@ -5372,7 +5112,7 @@ seed_random() # endif /* HASRANDOM */ #endif /* HASSRANDOMDEV */ } -/* +/* ** SM_SYSLOG -- syslog wrapper to keep messages under SYSLOG_BUFSIZE ** ** Parameters: @@ -5404,17 +5144,23 @@ sm_syslog(level, id, fmt, va_alist) int seq = 1; int idlen; char buf0[MAXLINE]; - extern int SnprfOverflow; - extern int SyslogErrno; - extern char *DoprEnd; - VA_LOCAL_DECL + char *newstring; + extern int SyslogPrefixLen; + SM_VA_LOCAL_DECL - save_errno = SyslogErrno = errno; + save_errno = errno; if (id == NULL) + { id = "NOQUEUE"; + idlen = strlen(id) + SyslogPrefixLen; + } else if (strcmp(id, NOQID) == 0) + { id = ""; - idlen = strlen(id); + idlen = SyslogPrefixLen; + } + else + idlen = strlen(id) + SyslogPrefixLen; if (buf == NULL) { @@ -5424,38 +5170,43 @@ sm_syslog(level, id, fmt, va_alist) for (;;) { - /* do a virtual vsnprintf into buf */ - VA_START(fmt); - buf[0] = 0; - DoprEnd = buf + bufsize - 1; - SnprfOverflow = 0; - sm_dopr(buf, fmt, ap); - *DoprEnd = '\0'; - VA_END; - /* end of virtual vsnprintf */ - - if (SnprfOverflow == 0) + int n; + + /* print log message into buf */ + SM_VA_START(ap, fmt); + n = sm_vsnprintf(buf, bufsize, fmt, ap); + SM_VA_END(ap); + SM_ASSERT(n > 0); + if (n < bufsize) break; /* String too small, redo with correct size */ - bufsize += SnprfOverflow + 1; + bufsize = n + 1; if (buf != buf0) + { sm_free(buf); - buf = xalloc(bufsize * sizeof (char)); + buf = NULL; + } + buf = sm_malloc_x(bufsize); } - if ((strlen(buf) + idlen + 1) < SYSLOG_BUFSIZE) + + /* clean up buf after it has been expanded with args */ + newstring = str2prt(buf); + if ((strlen(newstring) + idlen + 1) < SYSLOG_BUFSIZE) { #if LOG if (*id == '\0') - syslog(level, "%s", buf); + syslog(level, "%s", newstring); else - syslog(level, "%s: %s", id, buf); + syslog(level, "%s: %s", id, newstring); #else /* LOG */ /*XXX should do something more sensible */ if (*id == '\0') - fprintf(stderr, "%s\n", buf); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s\n", + newstring); else - fprintf(stderr, "%s: %s\n", id, buf); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s: %s\n", id, newstring); #endif /* LOG */ if (buf == buf0) buf = NULL; @@ -5463,18 +5214,26 @@ sm_syslog(level, id, fmt, va_alist) return; } - begin = buf; +/* +** additional length for splitting: " ..." + 3, where 3 is magic to +** have some data for the next entry. +*/ + +#define SL_SPLIT 7 + + begin = newstring; + idlen += 5; /* strlen("[999]"), see below */ while (*begin != '\0' && - (strlen(begin) + idlen + 5) > SYSLOG_BUFSIZE) + (strlen(begin) + idlen) > SYSLOG_BUFSIZE) { char save; - if (seq == 999) + if (seq >= 999) { /* Too many messages */ break; } - end = begin + SYSLOG_BUFSIZE - idlen - 12; + end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT; while (end > begin) { /* Break on comma or space */ @@ -5487,36 +5246,38 @@ sm_syslog(level, id, fmt, va_alist) } /* No separator, break midstring... */ if (end == begin) - end = begin + SYSLOG_BUFSIZE - idlen - 12; + end = begin + SYSLOG_BUFSIZE - idlen - SL_SPLIT; save = *end; *end = 0; #if LOG syslog(level, "%s[%d]: %s ...", id, seq++, begin); #else /* LOG */ - fprintf(stderr, "%s[%d]: %s ...\n", id, seq++, begin); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s[%d]: %s ...\n", id, seq++, begin); #endif /* LOG */ *end = save; begin = end; } - if (seq == 999) + if (seq >= 999) #if LOG syslog(level, "%s[%d]: log terminated, too many parts", id, seq); #else /* LOG */ - fprintf(stderr, "%s[%d]: log terminated, too many parts\n", - id, seq); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s[%d]: log terminated, too many parts\n", id, seq); #endif /* LOG */ else if (*begin != '\0') #if LOG syslog(level, "%s[%d]: %s", id, seq, begin); #else /* LOG */ - fprintf(stderr, "%s[%d]: %s\n", id, seq, begin); + (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, + "%s[%d]: %s\n", id, seq, begin); #endif /* LOG */ if (buf == buf0) buf = NULL; errno = save_errno; } -/* +/* ** HARD_SYSLOG -- call syslog repeatedly until it works ** ** Needed on HP-UX, which apparently doesn't guarantee that @@ -5547,11 +5308,11 @@ hard_syslog(pri, msg, va_alist) { int i; char buf[SYSLOG_BUFSIZE]; - VA_LOCAL_DECL; + SM_VA_LOCAL_DECL - VA_START(msg); - vsnprintf(buf, sizeof buf, msg, ap); - VA_END; + SM_VA_START(ap, msg); + (void) sm_vsnprintf(buf, sizeof buf, msg, ap); + SM_VA_END(ap); for (i = MAXSYSLOGTRIES; --i >= 0 && syslog(pri, CAST "%s", buf) < 0; ) continue; @@ -5560,7 +5321,7 @@ hard_syslog(pri, msg, va_alist) # undef CAST #endif /* defined(__hpux) && !defined(HPUX11) */ #if NEEDLOCAL_HOSTNAME_LENGTH -/* +/* ** LOCAL_HOSTNAME_LENGTH ** ** This is required to get sendmail to compile against BIND 4.9.x @@ -5575,14 +5336,14 @@ int local_hostname_length(hostname) char *hostname; { - int len_host, len_domain; + size_t len_host, len_domain; if (!*_res.defdname) res_init(); len_host = strlen(hostname); len_domain = strlen(_res.defdname); if (len_host > len_domain && - (strcasecmp(hostname + len_host - len_domain, + (sm_strcasecmp(hostname + len_host - len_domain, _res.defdname) == 0) && hostname[len_host - len_domain - 1] == '.') return len_host - len_domain - 1; @@ -5591,36 +5352,150 @@ local_hostname_length(hostname) } #endif /* NEEDLOCAL_HOSTNAME_LENGTH */ -/* +#if NEEDLINK +/* +** LINK -- clone a file +** +** Some OS's lacks link() and hard links. Since sendmail is using +** link() as an efficient way to clone files, this implementation +** will simply do a file copy. +** +** NOTE: This link() replacement is not a generic replacement as it +** does not handle all of the semantics of the real link(2). +** +** Parameters: +** source -- pathname of existing file. +** target -- pathname of link (clone) to be created. +** +** Returns: +** 0 -- success. +** -1 -- failure, see errno for details. +*/ + +int +link(source, target) + const char *source; + const char *target; +{ + int save_errno; + int sff; + int src = -1, dst = -1; + ssize_t readlen; + ssize_t writelen; + char buf[BUFSIZ]; + struct stat st; + + sff = SFF_REGONLY|SFF_OPENASROOT; + if (DontLockReadFiles) + sff |= SFF_NOLOCK; + + /* Open the original file */ + src = safeopen((char *)source, O_RDONLY, 0, sff); + if (src < 0) + goto fail; + + /* Obtain the size and the mode */ + if (fstat(src, &st) < 0) + goto fail; + + /* Create the duplicate copy */ + sff &= ~SFF_NOLOCK; + sff |= SFF_CREAT; + dst = safeopen((char *)target, O_CREAT|O_EXCL|O_WRONLY, + st.st_mode, sff); + if (dst < 0) + goto fail; + + /* Copy all of the bytes one buffer at a time */ + while ((readlen = read(src, &buf, sizeof(buf))) > 0) + { + ssize_t left = readlen; + char *p = buf; + + while (left > 0 && + (writelen = write(dst, p, (size_t) left)) >= 0) + { + left -= writelen; + p += writelen; + } + if (writeln < 0) + break; + } + + /* Any trouble reading? */ + if (readlen < 0 || writelen < 0) + goto fail; + + /* Close the input file */ + if (close(src) < 0) + { + src = -1; + goto fail; + } + src = -1; + + /* Close the output file */ + if (close(dst) < 0) + { + /* don't set dst = -1 here so we unlink the file */ + goto fail; + } + + /* Success */ + return 0; + + fail: + save_errno = errno; + if (src >= 0) + (void) close(src); + if (dst >= 0) + { + (void) unlink(target); + (void) close(dst); + } + errno = save_errno; + return -1; +} +#endif /* NEEDLINK */ + +/* ** Compile-Time options */ char *CompileOptions[] = { +#if NAMED_BIND +# if DNSMAP + "DNSMAP", +# endif /* DNSMAP */ +#endif /* NAMED_BIND */ #if EGD "EGD", #endif /* EGD */ -#ifdef HESIOD +#if HESIOD "HESIOD", #endif /* HESIOD */ #if HES_GETMAILHOST "HES_GETMAILHOST", #endif /* HES_GETMAILHOST */ -#ifdef LDAPMAP +#if LDAPMAP "LDAPMAP", #endif /* LDAPMAP */ -#ifdef MAP_NSD +#if LOG + "LOG", +#endif /* LOG */ +#if MAP_NSD "MAP_NSD", #endif /* MAP_NSD */ -#ifdef MAP_REGEX +#if MAP_REGEX "MAP_REGEX", #endif /* MAP_REGEX */ -#if LOG - "LOG", -#endif /* LOG */ #if MATCHGECOS "MATCHGECOS", #endif /* MATCHGECOS */ +#if MILTER + "MILTER", +#endif /* MILTER */ #if MIME7TO8 "MIME7TO8", #endif /* MIME7TO8 */ @@ -5630,7 +5505,7 @@ char *CompileOptions[] = #if NAMED_BIND "NAMED_BIND", #endif /* NAMED_BIND */ -#ifdef NDBM +#if NDBM "NDBM", #endif /* NDBM */ #if NETINET @@ -5654,52 +5529,58 @@ char *CompileOptions[] = #if NETX25 "NETX25", #endif /* NETX25 */ -#ifdef NEWDB +#if NEWDB "NEWDB", #endif /* NEWDB */ -#ifdef NIS +#if NIS "NIS", #endif /* NIS */ -#ifdef NISPLUS +#if NISPLUS "NISPLUS", #endif /* NISPLUS */ -#ifdef PH_MAP +#if NO_DH + "NO_DH", +#endif /* NO_DH */ +#if PH_MAP "PH_MAP", #endif /* PH_MAP */ -#if QUEUE - "QUEUE", -#endif /* QUEUE */ +#ifdef PICKY_HELO_CHECK + "PICKY_HELO_CHECK", +#endif /* PICKY_HELO_CHECK */ +#if PIPELINING + "PIPELINING", +#endif /* PIPELINING */ #if SASL "SASL", #endif /* SASL */ #if SCANF "SCANF", #endif /* SCANF */ -#if SFIO - "SFIO", -#endif /* SFIO */ -#if SMTP - "SMTP", -#endif /* SMTP */ #if SMTPDEBUG "SMTPDEBUG", #endif /* SMTPDEBUG */ #if STARTTLS "STARTTLS", #endif /* STARTTLS */ -#ifdef SUID_ROOT_FILES_OK +#if SUID_ROOT_FILES_OK "SUID_ROOT_FILES_OK", #endif /* SUID_ROOT_FILES_OK */ #if TCPWRAPPERS "TCPWRAPPERS", #endif /* TCPWRAPPERS */ +#if TLS_NO_RSA + "TLS_NO_RSA", +#endif /* TLS_NO_RSA */ +#if TLS_VRFY_PER_CTX + "TLS_VRFY_PER_CTX", +#endif /* TLS_VRFY_PER_CTX */ #if USERDB "USERDB", #endif /* USERDB */ #if XDEBUG "XDEBUG", #endif /* XDEBUG */ -#ifdef XLA +#if XLA "XLA", #endif /* XLA */ NULL @@ -5712,9 +5593,27 @@ char *CompileOptions[] = char *OsCompileOptions[] = { +#if ADDRCONFIG_IS_BROKEN + "ADDRCONFIG_IS_BROKEN", +#endif /* ADDRCONFIG_IS_BROKEN */ +#ifdef AUTO_NETINFO_HOSTS + "AUTO_NETINFO_HOSTS", +#endif /* AUTO_NETINFO_HOSTS */ +#ifdef AUTO_NIS_ALIASES + "AUTO_NIS_ALIASES", +#endif /* AUTO_NIS_ALIASES */ +#if BROKEN_RES_SEARCH + "BROKEN_RES_SEARCH", +#endif /* BROKEN_RES_SEARCH */ +#ifdef BSD4_4_SOCKADDR + "BSD4_4_SOCKADDR", +#endif /* BSD4_4_SOCKADDR */ #if BOGUS_O_EXCL "BOGUS_O_EXCL", #endif /* BOGUS_O_EXCL */ +#if DEC_OSF_BROKEN_GETPWENT + "DEC_OSF_BROKEN_GETPWENT", +#endif /* DEC_OSF_BROKEN_GETPWENT */ #if FAST_PID_RECYCLE "FAST_PID_RECYCLE", #endif /* FAST_PID_RECYCLE */ @@ -5739,12 +5638,27 @@ char *OsCompileOptions[] = #if HASLSTAT "HASLSTAT", #endif /* HASLSTAT */ +#if HASNICE + "HASNICE", +#endif /* HASNICE */ #if HASRANDOM "HASRANDOM", #endif /* HASRANDOM */ +#if HASRRESVPORT + "HASRRESVPORT", +#endif /* HASRRESVPORT */ +#if HASSETEGID + "HASSETEGID", +#endif /* HASSETEGID */ #if HASSETLOGIN "HASSETLOGIN", #endif /* HASSETLOGIN */ +#if HASSETREGID + "HASSETREGID", +#endif /* HASSETREGID */ +#if HASSETRESGID + "HASSETRESGID", +#endif /* HASSETRESGID */ #if HASSETREUID "HASSETREUID", #endif /* HASSETREUID */ @@ -5760,9 +5674,6 @@ char *OsCompileOptions[] = #if HASSETVBUF "HASSETVBUF", #endif /* HASSETVBUF */ -#if HASSNPRINTF - "HASSNPRINTF", -#endif /* HASSNPRINTF */ #if HAS_ST_GEN "HAS_ST_GEN", #endif /* HAS_ST_GEN */ @@ -5799,9 +5710,30 @@ char *OsCompileOptions[] = #if NEEDFSYNC "NEEDFSYNC", #endif /* NEEDFSYNC */ +#if NEEDLINK + "NEEDLINK", +#endif /* NEEDLINK */ +#if NEEDLOCAL_HOSTNAME_LENGTH + "NEEDLOCAL_HOSTNAME_LENGTH", +#endif /* NEEDLOCAL_HOSTNAME_LENGTH */ +#if NEEDSGETIPNODE + "NEEDSGETIPNODE", +#endif /* NEEDSGETIPNODE */ +#if NEEDSTRSTR + "NEEDSTRSTR", +#endif /* NEEDSTRSTR */ +#if NEEDSTRTOL + "NEEDSTRTOL", +#endif /* NEEDSTRTOL */ +#ifdef NO_GETSERVBYNAME + "NO_GETSERVBYNAME", +#endif /* NO_GETSERVBYNAME */ #if NOFTRUNCATE "NOFTRUNCATE", #endif /* NOFTRUNCATE */ +#if REQUIRES_DIR_FSYNC + "REQUIRES_DIR_FSYNC", +#endif /* REQUIRES_DIR_FSYNC */ #if RLIMIT_NEEDS_SYS_TIME_H "RLIMIT_NEEDS_SYS_TIME_H", #endif /* RLIMIT_NEEDS_SYS_TIME_H */ @@ -5832,15 +5764,167 @@ char *OsCompileOptions[] = #if SYSTEM5 "SYSTEM5", #endif /* SYSTEM5 */ +#if USE_DOUBLE_FORK + "USE_DOUBLE_FORK", +#endif /* USE_DOUBLE_FORK */ +#if USE_ENVIRON + "USE_ENVIRON", +#endif /* USE_ENVIRON */ #if USE_SA_SIGACTION "USE_SA_SIGACTION", #endif /* USE_SA_SIGACTION */ #if USE_SIGLONGJMP "USE_SIGLONGJMP", #endif /* USE_SIGLONGJMP */ +#if USEGETCONFATTR + "USEGETCONFATTR", +#endif /* USEGETCONFATTR */ #if USESETEUID "USESETEUID", #endif /* USESETEUID */ +#ifdef USESYSCTL + "USESYSCTL", +#endif /* USESYSCTL */ +#if USING_NETSCAPE_LDAP + "USING_NETSCAPE_LDAP", +#endif /* USING_NETSCAPE_LDAP */ +#ifdef WAITUNION + "WAITUNION", +#endif /* WAITUNION */ + NULL +}; + +/* +** FFR compile options. +*/ + +char *FFRCompileOptions[] = +{ +#if _FFR_ADAPTIVE_EOL + "_FFR_ADAPTIVE_EOL", +#endif /* _FFR_ADAPTIVE_EOL */ +#if _FFR_ALLOW_SASLINFO + "_FFR_ALLOW_SASLINFO", +#endif /* _FFR_ALLOW_SASLINFO */ +#if _FFR_BESTMX_BETTER_TRUNCATION + "_FFR_BESTMX_BETTER_TRUNCATION", +#endif /* _FFR_BESTMX_BETTER_TRUNCATION */ +#if _FFR_CACHE_LPC +/* Christophe Wolfhugel of France Telecom Oleane */ + "_FFR_CACHE_LPC", +#endif /* _FFR_CACHE_LPC */ +#if _FFR_CATCH_BROKEN_MTAS + "_FFR_CATCH_BROKEN_MTAS", +#endif /* _FFR_CATCH_BROKEN_MTAS */ +#if _FFR_CHECK_EOM + "_FFR_CHECK_EOM", +#endif /* _FFR_CHECK_EOM */ +#if _FFR_CONTROL_MSTAT + "_FFR_CONTROL_MSTAT", +#endif /* _FFR_CONTROL_MSTAT */ +#if _FFR_DAEMON_NETUNIX + "_FFR_DAEMON_NETUNIX", +#endif /* _FFR_DAEMON_NETUNIX */ +#if _FFR_DEPRECATE_MAILER_FLAG_I + "_FFR_DEPRECATE_MAILER_FLAG_I", +#endif /* _FFR_DEPRECATE_MAILER_FLAG_I */ +#if _FFR_DNSMAP_BASE + "_FFR_DNSMAP_BASE", +#endif /* _FFR_DNSMAP_BASE */ +#if _FFR_DNSMAP_MULTI + "_FFR_DNSMAP_MULTI", +# if _FFR_DNSMAP_MULTILIMIT + "_FFR_DNSMAP_MULTILIMIT", +# endif /* _FFR_DNSMAP_MULTILIMIT */ +#endif /* _FFR_DNSMAP_MULTI */ +#if _FFR_DONTLOCKFILESFORREAD_OPTION + "_FFR_DONTLOCKFILESFORREAD_OPTION", +#endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */ +#if _FFR_DOTTED_USERNAMES + "_FFR_DOTTED_USERNAMES", +#endif /* _FFR_DOTTED_USERNAMES */ +#if _FFR_DROP_TRUSTUSER_WARNING + "_FFR_DROP_TRUSTUSER_WARNING", +#endif /* _FFR_DROP_TRUSTUSER_WARNING */ +#if _FFR_FIX_DASHT + "_FFR_FIX_DASHT", +#endif /* _FFR_FIX_DASHT */ +#if _FFR_FORWARD_SYSERR + "_FFR_FORWARD_SYSERR", +#endif /* _FFR_FORWARD_SYSERR */ +#if _FFR_GEN_ORCPT + "_FFR_GEN_ORCPT", +#endif /* _FFR_GEN_ORCPT */ +#if _FFR_GROUPREADABLEAUTHINFOFILE + "_FFR_GROUPREADABLEAUTHINFOFILE", +#endif /* _FFR_GROUPREADABLEAUTHINFOFILE */ +#if _FFR_HDR_TYPE + "_FFR_HDR_TYPE", +#endif /* _FFR_HDR_TYPE */ +#if _FFR_HPUX_NSSWITCH + "_FFR_HPUX_NSSWITCH", +#endif /* _FFR_HPUX_NSSWITCH */ +#if _FFR_IGNORE_EXT_ON_HELO + "_FFR_IGNORE_EXT_ON_HELO", +#endif /* _FFR_IGNORE_EXT_ON_HELO */ +#if _FFR_LDAP_RECURSION + "_FFR_LDAP_RECURSION", +#endif /* _FFR_LDAP_RECURSION */ +#if _FFR_MAX_FORWARD_ENTRIES +/* Randall S. Winchester of the University of Maryland */ + "_FFR_MAX_FORWARD_ENTRIES", +#endif /* _FFR_MAX_FORWARD_ENTRIES */ +#if MILTER +# if _FFR_MILTER_PERDAEMON + "_FFR_MILTER_PERDAEMON", +# endif /* _FFR_MILTER_PERDAEMON */ +#endif /* MILTER */ +#if _FFR_NODELAYDSN_ON_HOLD +/* Steven Pitzl */ + "_FFR_NODELAYDSN_ON_HOLD", +#endif /* _FFR_NODELAYDSN_ON_HOLD */ +#if _FFR_NO_PIPE + "_FFR_NO_PIPE", +#endif /* _FFR_NO_PIPE */ +#if _FFR_QUARANTINE + "_FFR_QUARANTINE", +#endif /* _FFR_QUARANTINE */ +#if _FFR_QUEUEDELAY + "_FFR_QUEUEDELAY", +#endif /* _FFR_QUEUEDELAY */ +#if _FFR_QUEUE_MACRO + "_FFR_QUEUE_MACRO", +#endif /* _FFR_QUEUE_MACRO */ +#if _FFR_QUEUE_SCHED_DBG + "_FFR_QUEUE_SCHED_DBG", +#endif /* _FFR_QUEUE_SCHED_DBG */ +#if _FFR_REDIRECTEMPTY + "_FFR_REDIRECTEMPTY", +#endif /* _FFR_REDIRECTEMPTY */ +#if _FFR_RESET_MACRO_GLOBALS + "_FFR_RESET_MACRO_GLOBALS", +#endif /* _FFR_RESET_MACRO_GLOBALS */ +#if _FFR_RHS + "_FFR_RHS", +#endif /* _FFR_RHS */ +#if _FFR_SHM_STATUS + "_FFR_SHM_STATUS", +#endif /* _FFR_SHM_STATUS */ +#if _FFR_SMTP_SSL + "_FFR_SMTP_SSL", +#endif /* _FFR_SMTP_SSL */ +#if _FFR_SOFT_BOUNCE + "_FFR_SOFT_BOUNCE", +#endif /* _FFR_SOFT_BOUNCE */ +#if _FFR_TIMERS + "_FFR_TIMERS", +#endif /* _FFR_TIMERS */ +#if _FFR_TLS_1 + "_FFR_TLS_1", +#endif /* _FFR_TLS_1 */ +#if _FFR_TRUSTED_QF + "_FFR_TRUSTED_QF", +#endif /* _FFR_TRUSTED_QF */ NULL }; diff --git a/contrib/sendmail/src/conf.h b/contrib/sendmail/src/conf.h index 0093ceb..9a4645d 100644 --- a/contrib/sendmail/src/conf.h +++ b/contrib/sendmail/src/conf.h @@ -10,7 +10,7 @@ * the sendmail distribution. * * - * $Id: conf.h,v 8.496.4.54 2001/07/31 22:30:24 gshapiro Exp $ + * $Id: conf.h,v 8.557 2001/10/05 03:49:41 ca Exp $ */ /* $FreeBSD$ */ @@ -31,9 +31,6 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ # include <sys/param.h> # include <sys/types.h> -# if SFIO && defined(SF_APPEND) -# undef SF_APPEND /* Both sfio/stdio.h and sys/stat.h define it */ -# endif /* SFIO && defined(SF_APPEND) */ # include <sys/stat.h> # ifndef __QNX__ /* in QNX this grabs bogus LOCK_* manifests */ @@ -61,6 +58,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ /********************************************************************** ** Table sizes, etc.... ** There shouldn't be much need to change these.... +** If you do, be careful, none should be set anywhere near INT_MAX **********************************************************************/ #define MAXLINE 2048 /* max line length */ @@ -74,19 +72,26 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ #define MAXKEY 128 /* maximum size of a database key */ #define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */ #define MAXUSERENVIRON 100 /* max envars saved, must be >= 3 */ -#define MAXALIASDB 12 /* max # of alias databases */ #define MAXMAPSTACK 12 /* max # of stacked or sequenced maps */ -#if _FFR_MILTER +#if MILTER # define MAXFILTERS 25 /* max # of milter filters */ -# define MAXFILTERMACROS 50 /* max # of macros per milter cmd */ -#endif /* _FFR_MILTER */ +# define MAXFILTERMACROS 50 /* max # of macros per milter cmd */ +#endif /* MILTER */ #define MAXSMTPARGS 20 /* max # of ESMTP args for MAIL/RCPT */ #define MAXTOCLASS 8 /* max # of message timeout classes */ #define MAXRESTOTYPES 3 /* max # of resolver timeout types */ #define MAXMIMEARGS 20 /* max args in Content-Type: */ #define MAXMIMENESTING 20 /* max MIME multipart nesting */ #define QUEUESEGSIZE 1000 /* increment for queue size */ -#define MAXQFNAME 21 /* max qf file name length */ + +/* +** MAXQFNAME == 2 (size of "qf", "df" prefix) +** + 8 (base 60 encoded date, time & sequence number) +** + 10 (base 10 encoded 32 bit process id) +** + 1 (terminating NUL character). +*/ + +#define MAXQFNAME 21 /* max qf file name length + 1 */ #define MACBUFSIZE 4096 /* max expanded macro buffer size */ #define TOBUFSIZE SM_ARG_MAX /* max buffer to hold address list */ #define MAXSHORTSTR 203 /* max short string length */ @@ -104,28 +109,32 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ # define MAXSYMLINKS 32 /* max number of symlinks in a path */ #endif /* ! MAXSYMLINKS */ #define MAXLINKPATHLEN (MAXPATHLEN * MAXSYMLINKS) /* max link-expanded file */ -#define DATA_PROGRESS_TIMEOUT 300 /* how ofter to check DATA progress */ +#define DATA_PROGRESS_TIMEOUT 300 /* how often to check DATA progress */ #define ENHSCLEN 10 /* max len of enhanced status code */ -#if _FFR_DYNAMIC_TOBUF -# define DEFAULT_MAX_RCPT 100 /* max number of RCPTs per envelope */ -#endif /* _FFR_DYNAMIC_TOBUF */ +#define DEFAULT_MAX_RCPT 100 /* max number of RCPTs per envelope */ +#define MAXQUEUEGROUPS 50 /* max # of queue groups */ + /* must be less than BITMAPBITS for DoQueueRun */ +#define MAXWORKGROUPS 50 /* max # of work groups */ +#define MAXFILESYS BITMAPBITS /* max # of queue file systems + * must be <= BITMAPBITS */ +#ifndef FILESYS_UPDATE_INTERVAL +# define FILESYS_UPDATE_INTERVAL 300 /* how often to update FileSys table */ +#endif /* FILESYS_UPDATE_INTERVAL */ + +#ifndef SM_DEFAULT_TTL +# define SM_DEFAULT_TTL 3600 /* default TTL for services that don't have one */ +#endif /* SM_DEFAULT_TTL */ #if SASL # ifndef AUTH_MECHANISMS -# if STARTTLS && _FFR_EXT_MECH +# if STARTTLS # define AUTH_MECHANISMS "EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5" -# else /* STARTTLS && _FFR_EXT_MECH */ +# else /* STARTTLS */ # define AUTH_MECHANISMS "GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5" -# endif /* STARTTLS && _FFR_EXT_MECH */ +# endif /* STARTTLS */ # endif /* ! AUTH_MECHANISMS */ #endif /* SASL */ -#ifdef LDAPMAP -# define LDAPMAP_MAX_ATTR 64 -# define LDAPMAP_MAX_FILTER 1024 -# define LDAPMAP_MAX_PASSWD 256 -#endif /* LDAPMAP */ - /********************************************************************** ** Compilation options. ** #define these to 1 if they are available; @@ -173,2680 +182,20 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ # define MIME7TO8 1 /* 7->8 bit MIME conversions */ #endif /* ! MIME7TO8 */ -/********************************************************************** -** "Hard" compilation options. -** #define these if they are available; comment them out otherwise. -** These cannot be overridden from the Makefile, and should really not -** be turned off unless absolutely necessary. -**********************************************************************/ +#if NAMED_BIND +# ifndef DNSMAP +# define DNSMAP 1 /* DNS map type */ +# endif /* ! DNSMAP */ +#endif /* NAMED_BIND */ -#define LOG 1 /* enable logging -- don't turn off */ +#ifndef PIPELINING +# define PIPELINING 1 /* SMTP PIPELINING */ +#endif /* PIPELINING */ /********************************************************************** ** End of site-specific configuration. **********************************************************************/ -/* -** General "standard C" defines. -** -** These may be undone later, to cope with systems that claim to -** be Standard C but aren't. Gcc is the biggest offender -- it -** doesn't realize that the library is part of the language. -** -** Life would be much easier if we could get rid of this sort -** of bozo problems. -*/ - -#ifdef __STDC__ -# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ -#endif /* __STDC__ */ - -/* -** Assume you have standard calls; can be #undefed below if necessary. -*/ - -#ifndef HASLSTAT -# define HASLSTAT 1 /* has lstat(2) call */ -#endif /* ! HASLSTAT */ -/********************************************************************** -** Operating system configuration. -** -** Unless you are porting to a new OS, you shouldn't have to -** change these. -**********************************************************************/ - -/* -** HP-UX -- tested for 8.07, 9.00, and 9.01. -** -** If V4FS is defined, compile for HP-UX 10.0. -** 11.x support from Richard Allen <ra@hp.is>. -*/ - -#ifdef __hpux - /* common definitions for HP-UX 9.x and 10.x */ -# undef m_flags /* conflict between Berkeley DB 1.85 db.h & sys/sysmacros.h on HP 300 */ -# define SYSTEM5 1 /* include all the System V defines */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define USESETEUID 1 /* has usable seteuid(2) call */ -# define BOGUS_O_EXCL 1 /* exclusive open follows symlinks */ -# define seteuid(e) setresuid(-1, e, -1) -# define IP_SRCROUTE 1 /* can check IP source routing */ -# define LA_TYPE LA_HPUX -# define SPT_TYPE SPT_PSTAT -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# define GIDSET_T gid_t -# ifndef HASGETUSERSHELL -# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */ -# endif /* ! HASGETUSERSHELL */ -# ifdef HPUX11 -# define HASFCHOWN 1 /* has fchown(2) */ -# define HASSNPRINTF 1 /* has snprintf(3) */ -# ifndef BROKEN_RES_SEARCH -# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */ -# endif /* ! BROKEN_RES_SEARCH */ -# else /* HPUX11 */ -# ifndef NOT_SENDMAIL -# define syslog hard_syslog -# endif /* ! NOT_SENDMAIL */ -# endif /* HPUX11 */ -# define SAFENFSPATHCONF 1 /* pathconf(2) pessimizes on NFS filesystems */ - -# ifdef V4FS - /* HP-UX 10.x */ -# define _PATH_UNIX "/stand/vmunix" -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -# ifndef IDENTPROTO -# define IDENTPROTO 1 /* TCP/IP implementation fixed in 10.0 */ -# endif /* ! IDENTPROTO */ -# include <sys/mpctl.h> /* for mpctl() in get_num_procs_online() */ -# else /* V4FS */ - /* HP-UX 9.x */ -# define _PATH_UNIX "/hp-ux" -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -# ifdef __STDC__ -extern void hard_syslog(int, char *, ...); -# else /* __STDC__ */ -extern void hard_syslog(); -# endif /* __STDC__ */ -# define FDSET_CAST (int *) /* cast for fd_set parameters to select */ -# endif /* V4FS */ - -#endif /* __hpux */ - - -/* -** IBM AIX 4.x -*/ - -#ifdef _AIX4 -# define _AIX3 1 /* pull in AIX3 stuff */ -# define BSD4_4_SOCKADDR /* has sa_len */ -# define USESETEUID 1 /* seteuid(2) works */ -# define TZ_TYPE TZ_NAME /* use tzname[] vector */ -# define SOCKOPT_LEN_T size_t /* arg#5 to getsockopt */ -# if _AIX4 >= 40200 -# define HASSETREUID 1 /* setreuid(2) works as of AIX 4.2 */ -# define SOCKADDR_LEN_T size_t /* e.g., arg#3 to accept, getsockname */ -# endif /* _AIX4 >= 40200 */ -# if _AIX4 >= 40300 -# define HASSNPRINTF 1 /* has snprintf starting in 4.3 */ -# endif /* _AIX4 >= 40300 */ -# if defined(_ILS_MACROS) /* IBM versions aren't side-effect clean */ -# undef isascii -# define isascii(c) !(c & ~0177) -# undef isdigit -# define isdigit(__a) (_IS(__a,_ISDIGIT)) -# undef isspace -# define isspace(__a) (_IS(__a,_ISSPACE)) -# endif /* defined(_ILS_MACROS) */ -#endif /* _AIX4 */ - - -/* -** IBM AIX 3.x -- actually tested for 3.2.3 -*/ - -#ifdef _AIX3 -# include <paths.h> -# include <sys/machine.h> /* to get byte order */ -# include <sys/select.h> -# define HASFCHOWN 1 /* has fchown(2) */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */ -# define GIDSET_T gid_t -# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */ -# define SPT_PADCHAR '\0' /* pad process title with nulls */ -# define LA_TYPE LA_INT -# define FSHIFT 16 -# define LA_AVENRUN "avenrun" -#endif /* _AIX3 */ - - -/* -** IBM AIX 2.2.1 -- actually tested for osupdate level 2706+1773 -** -** From Mark Whetzel <markw@wg.waii.com>. -*/ - -#ifdef AIX /* AIX/RT compiler pre-defines this */ -# include <paths.h> -# include <sys/time.h> /* AIX/RT resource.h does NOT include this */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# define HASFCHMOD 0 /* does not have fchmod(2) syscall */ -# define HASSETREUID 1 /* use setreuid(2) -lbsd system call */ -# define HASSETVBUF 1 /* use setvbuf(2) system call */ -# define HASSETRLIMIT 0 /* does not have setrlimit call */ -# define HASFLOCK 0 /* does not have flock call - use fcntl */ -# define HASULIMIT 1 /* use ulimit instead of setrlimit call */ -# define NEEDGETOPT 1 /* Do we need theirs or ours */ -# define SYS5SETPGRP 1 /* don't have setpgid on AIX/RT */ -# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */ -# define BSD4_3 1 /* NOT bsd 4.4 or posix signals */ -# define GIDSET_T int -# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */ -# define SPT_PADCHAR '\0' /* pad process title with nulls */ -# define LA_TYPE LA_SUBR /* use our ported loadavgd daemon */ -# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */ -# define ARBPTR_T int * -# define void int -typedef int pid_t; -/* RTisms for BSD compatibility, specified in the Makefile - define BSD 1 - define BSD_INCLUDES 1 - define BSD_REMAP_SIGNAL_TO_SIGVEC - RTisms needed above */ -/* make this sendmail in a completely different place */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/local/newmail/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/usr/local/newmail/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -#endif /* AIX */ - - -/* -** Silicon Graphics IRIX -** -** Compiles on 4.0.1. -** -** Use IRIX64 instead of IRIX for 64-bit IRIX (6.0). -** Use IRIX5 instead of IRIX for IRIX 5.x. -** -** This version tries to be adaptive using _MIPS_SIM: -** _MIPS_SIM == _ABIO32 (= 1) Abi: -32 on IRIX 6.2 -** _MIPS_SIM == _ABIN32 (= 2) Abi: -n32 on IRIX 6.2 -** _MIPS_SIM == _ABI64 (= 3) Abi: -64 on IRIX 6.2 -** -** _MIPS_SIM is 1 also on IRIX 5.3 -** -** IRIX64 changes from Mark R. Levinson <ml@cvdev.rochester.edu>. -** IRIX5 changes from Kari E. Hurtta <Kari.Hurtta@fmi.fi>. -** Adaptive changes from Kari E. Hurtta <Kari.Hurtta@fmi.fi>. -*/ - -#if defined(__sgi) -# ifndef IRIX -# define IRIX -# endif /* ! IRIX */ -# if _MIPS_SIM > 0 && !defined(IRIX5) -# define IRIX5 /* IRIX5 or IRIX6 */ -# endif /* _MIPS_SIM > 0 && !defined(IRIX5) */ -# if _MIPS_SIM > 1 && !defined(IRIX6) && !defined(IRIX64) -# define IRIX6 /* IRIX6 */ -# endif /* _MIPS_SIM > 1 && !defined(IRIX6) && !defined(IRIX64) */ -#endif /* defined(__sgi) */ - -#ifdef IRIX -# define SYSTEM5 1 /* this is a System-V derived system */ -# define HASSETREUID 1 /* has setreuid(2) call */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# define IP_SRCROUTE 1 /* can check IP source routing */ -# define setpgid BSDsetpgrp -# define GIDSET_T gid_t -# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ -# define SFS_BAVAIL f_bfree /* alternate field name */ -# define SYSLOG_BUFSIZE 512 -# ifdef IRIX6 -# define STAT64 1 -# define QUAD_T unsigned long long -# define LA_TYPE LA_IRIX6 /* figure out at run time */ -# define SAFENFSPATHCONF 0 /* pathconf(2) lies on NFS filesystems */ -# else /* IRIX6 */ -# define LA_TYPE LA_INT - -# ifdef IRIX64 -# define STAT64 1 -# define QUAD_T unsigned long long -# define NAMELISTMASK 0x7fffffffffffffff /* mask for nlist() values */ -# else /* IRIX64 */ -# define STAT64 0 -# define NAMELISTMASK 0x7fffffff /* mask for nlist() values */ -# endif /* IRIX64 */ -# endif /* IRIX6 */ -# if defined(IRIX64) || defined(IRIX5) || defined(IRIX6) -# include <sys/cdefs.h> -# include <paths.h> -# define ARGV_T char *const * -# define HASFCHOWN 1 /* has fchown(2) */ -# define HASSETRLIMIT 1 /* has setrlimit(2) syscall */ -# define HASGETDTABLESIZE 1 /* has getdtablesize(2) syscall */ -# define HASSTRERROR 1 /* has strerror(3) */ -# else /* defined(IRIX64) || defined(IRIX5) || defined(IRIX6) */ -# define ARGV_T const char ** -# define WAITUNION 1 /* use "union wait" as wait argument type */ -# endif /* defined(IRIX64) || defined(IRIX5) || defined(IRIX6) */ -#endif /* IRIX */ - - -/* -** SunOS and Solaris -** -** Tested on SunOS 4.1.x (a.k.a. Solaris 1.1.x) and -** Solaris 2.4 (a.k.a. SunOS 5.4). -*/ - -#if defined(sun) && !defined(BSD) - -# include <sys/time.h> -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define IP_SRCROUTE 1 /* can check IP source routing */ -# define SAFENFSPATHCONF 1 /* pathconf(2) pessimizes on NFS filesystems */ -# ifndef HASFCHOWN -# define HASFCHOWN 1 /* fchown(2) */ -# endif /* ! HASFCHOWN */ - -# ifdef SOLARIS_2_3 -# define SOLARIS 20300 /* for back compat only -- use -DSOLARIS=20300 */ -# endif /* SOLARIS_2_3 */ - -# if defined(NOT_SENDMAIL) && !defined(SOLARIS) && defined(sun) && (defined(__svr4__) || defined(__SVR4)) -# define SOLARIS 1 /* unknown Solaris version */ -# endif /* defined(NOT_SENDMAIL) && !defined(SOLARIS) && defined(sun) && (defined(__svr4__) || defined(__SVR4)) */ - -# ifdef SOLARIS - /* Solaris 2.x (a.k.a. SunOS 5.x) */ -# ifndef __svr4__ -# define __svr4__ /* use all System V Release 4 defines below */ -# endif /* ! __svr4__ */ -# define GIDSET_T gid_t -# define USE_SA_SIGACTION 1 /* use sa_sigaction field */ -# define HASSTRERROR 1 /* has strerror(3) */ -# if _FFR_MILTER -# define BROKEN_PTHREAD_SLEEP 1 /* sleep after pthread_create() fails */ -# endif /* _FFR_MILTER */ -# ifndef _PATH_UNIX -# define _PATH_UNIX "/dev/ksyms" -# endif /* ! _PATH_UNIX */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -# ifndef _PATH_HOSTS -# define _PATH_HOSTS "/etc/inet/hosts" -# endif /* ! _PATH_HOSTS */ -# ifndef SYSLOG_BUFSIZE -# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */ -# endif /* ! SYSLOG_BUFSIZE */ -# ifndef TZ_TYPE -# define TZ_TYPE TZ_TZNAME -# endif /* ! TZ_TYPE */ -# if SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203) -# define USESETEUID 1 /* seteuid works as of 2.3 */ -# endif /* SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203) */ -# if SOLARIS >= 20500 || (SOLARIS < 10000 && SOLARIS >= 205) -# define HASSETREUID 1 /* setreuid works as of 2.5 */ -# if SOLARIS < 207 || (SOLARIS > 10000 && SOLARIS < 20700) -# ifndef LA_TYPE -# define LA_TYPE LA_KSTAT /* use kstat(3k) -- may work in < 2.5 */ -# endif /* ! LA_TYPE */ -# ifndef RANDOMSHIFT /* random() doesn't work well (sometimes) */ -# define RANDOMSHIFT 8 -# endif /* RANDOMSHIFT */ -# endif /* SOLARIS < 207 || (SOLARIS > 10000 && SOLARIS < 20700) */ -# else /* SOLARIS >= 20500 || (SOLARIS < 10000 && SOLARIS >= 205) */ -# ifndef HASRANDOM -# define HASRANDOM 0 /* doesn't have random(3) */ -# endif /* ! HASRANDOM */ -# endif /* SOLARIS >= 20500 || (SOLARIS < 10000 && SOLARIS >= 205) */ -# if SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) -# define HASSNPRINTF 1 /* has snprintf starting in 2.6 */ -# else /* SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) */ -# if _FFR_MILTER -# define SM_INT32 int /* 32bit integer */ -# endif /* _FFR_MILTER */ -# endif /* SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) */ -# if SOLARIS >= 20700 || (SOLARIS < 10000 && SOLARIS >= 207) -# ifndef LA_TYPE -# include <sys/loadavg.h> -# if SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) -# include <sys/pset.h> -# define LA_TYPE LA_PSET /* pset_getloadavg(3c) appears in 2.9 */ -# else -# define LA_TYPE LA_SUBR /* getloadavg(3c) appears in 2.7 */ -# endif /* SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) */ -# endif /* ! LA_TYPE */ -# define HASGETUSERSHELL 1 /* getusershell(3c) bug fixed in 2.7 */ -# endif /* SOLARIS >= 20700 || (SOLARIS < 10000 && SOLARIS >= 207) */ -# if SOLARIS >= 20800 || (SOLARIS < 10000 && SOLARIS >= 208) -# define HASSTRL 1 /* str*(3) added in 2.8 */ -# undef _PATH_SENDMAILPID /* tmpfs /var/run added in 2.8 */ -# define _PATH_SENDMAILPID "/var/run/sendmail.pid" -# endif /* SOLARIS >= 20800 || (SOLARIS < 10000 && SOLARIS >= 208) */ -# if SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) -# define HASURANDOMDEV 1 /* /dev/[u]random added in S9 */ -# endif /* SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) */ -# ifndef HASGETUSERSHELL -# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps pre-2.7 */ -# endif /* ! HASGETUSERSHELL */ - -# else /* SOLARIS */ - /* SunOS 4.0.3 or 4.1.x */ -# define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */ -# define HASSETREUID 1 /* has setreuid(2) call */ -# ifndef HASFLOCK -# define HASFLOCK 1 /* has flock(2) call */ -# endif /* ! HASFLOCK */ -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */ -# include <memory.h> -# include <vfork.h> -# ifdef __GNUC__ -# define strtoul strtol /* gcc library bogosity */ -# endif /* __GNUC__ */ -# define memmove(d, s, l) (bcopy((s), (d), (l))) - -# ifdef SUNOS403 - /* special tweaking for SunOS 4.0.3 */ -# include <malloc.h> -# define BSD4_3 1 /* 4.3 BSD-based */ -# define NEEDSTRSTR 1 /* need emulation of strstr(3) routine */ -# define WAITUNION 1 /* use "union wait" as wait argument type */ -# undef WIFEXITED -# undef WEXITSTATUS -# undef HASUNAME -# define setpgid setpgrp -# define MODE_T int -typedef int pid_t; -extern char *getenv(); - -# else /* SUNOS403 */ - /* 4.1.x specifics */ -# define HASSETSID 1 /* has Posix setsid(2) call */ -# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ - -# endif /* SUNOS403 */ -# endif /* SOLARIS */ - -# ifndef LA_TYPE -# define LA_TYPE LA_INT -# endif /* ! LA_TYPE */ - -#endif /* defined(sun) && !defined(BSD) */ - -/* -** DG/UX -** -** Tested on 5.4.2 and 5.4.3. Use DGUX_5_4_2 to get the -** older support. -** 5.4.3 changes from Mark T. Robinson <mtr@ornl.gov>. -*/ - -#ifdef DGUX_5_4_2 -# define DGUX 1 -#endif /* DGUX_5_4_2 */ - -#ifdef DGUX -# define SYSTEM5 1 -# define LA_TYPE LA_DGUX -# define HASSETREUID 1 /* has setreuid(2) call */ -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASSETSID 1 /* has Posix setsid(2) call */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define IP_SRCROUTE 0 /* does not have <netinet/ip_var.h> */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) */ -# define HASSNPRINTF 1 /* has snprintf(3) */ -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -# define SPT_TYPE SPT_NONE /* don't use setproctitle */ -# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ - -/* these include files must be included early on DG/UX */ -# include <netinet/in.h> -# include <arpa/inet.h> - -/* compiler doesn't understand const? */ -# define const - -# ifdef DGUX_5_4_2 -# define inet_addr dgux_inet_addr -extern long dgux_inet_addr(); -# endif /* DGUX_5_4_2 */ -#endif /* DGUX */ - - -/* -** Digital Ultrix 4.2A or 4.3 -** -** Apparently, fcntl locking is broken on 4.2A, in that locks are -** not dropped when the process exits. This causes major problems, -** so flock is the only alternative. -*/ - -#ifdef ultrix -# define HASSETREUID 1 /* has setreuid(2) call */ -# define HASUNSETENV 1 /* has unsetenv(3) call */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASFCHOWN 1 /* has fchown(2) syscall */ -# ifndef HASFLOCK -# define HASFLOCK 1 /* has flock(2) call */ -# endif /* ! HASFLOCK */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# ifndef BROKEN_RES_SEARCH -# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */ -# endif /* ! BROKEN_RES_SEARCH */ -# if !defined(NEEDLOCAL_HOSTNAME_LENGTH) && NAMED_BIND && __RES >= 19931104 && __RES < 19950621 -# define NEEDLOCAL_HOSTNAME_LENGTH 1 /* see sendmail/README */ -# endif /* !defined(NEEDLOCAL_HOSTNAME_LENGTH) && NAMED_BIND && __RES >= 19931104 && __RES < 19950621 */ -# ifdef vax -# define LA_TYPE LA_FLOAT -# else /* vax */ -# define LA_TYPE LA_INT -# define LA_AVENRUN "avenrun" -# endif /* vax */ -# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* pre-4.4 TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -# define SYSLOG_BUFSIZE 256 -#endif /* ultrix */ - - -/* -** OSF/1 for KSR. -** -** Contributed by Todd C. Miller <Todd.Miller@cs.colorado.edu> -*/ - -#ifdef __ksr__ -# define __osf__ 1 /* get OSF/1 defines below */ -# ifndef TZ_TYPE -# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */ -# endif /* ! TZ_TYPE */ -#endif /* __ksr__ */ - - -/* -** OSF/1 for Intel Paragon. -** -** Contributed by Jeff A. Earickson <jeff@ssd.intel.com> -** of Intel Scalable Systems Divison. -*/ - -#ifdef __PARAGON__ -# define __osf__ 1 /* get OSF/1 defines below */ -# ifndef TZ_TYPE -# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */ -# endif /* ! TZ_TYPE */ -# define GIDSET_T gid_t -# define MAXNAMLEN NAME_MAX -#endif /* __PARAGON__ */ - - -/* -** Tru64 UNIX, formerly known as Digital UNIX, formerly known as DEC OSF/1 -** -** Tested for 3.2 and 4.0. -*/ - -#ifdef __osf__ -# define HASUNAME 1 /* has uname(2) call */ -# define HASUNSETENV 1 /* has unsetenv(3) call */ -# define USESETEUID 1 /* has usable seteuid(2) call */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASFCHOWN 1 /* has fchown(2) syscall */ -# define HASSETLOGIN 1 /* has setlogin(2) */ -# define IP_SRCROUTE 1 /* can check IP source routing */ -# define HAS_ST_GEN 1 /* has st_gen field in stat struct */ -# define GIDSET_T gid_t -# if _FFR_MILTER -# define SM_INT32 int /* 32bit integer */ -# endif /* _FFR_MILTER */ -# ifndef HASFLOCK -# define HASFLOCK 1 /* has flock(2) call */ -# endif /* ! HASFLOCK */ -# define LA_TYPE LA_ALPHAOSF -# define SFS_TYPE SFS_STATVFS /* use <sys/statvfs.h> statfs() impl */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/var/adm/sendmail/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/var/run/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -#endif /* __osf__ */ - - -/* -** NeXTstep -*/ - -#ifdef NeXT -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define NEEDPUTENV 2 /* need putenv(3) call; no setenv(3) call */ -# ifndef HASFLOCK -# define HASFLOCK 1 /* has flock(2) call */ -# endif /* ! HASFLOCK */ -# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ -# 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 setpgid setpgrp -# ifndef NOT_SENDMAIL -# define sleep sleepX -# endif /* ! NOT_SENDMAIL */ -# ifndef LA_TYPE -# define LA_TYPE LA_MACH -# endif /* ! LA_TYPE */ -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# ifndef _POSIX_SOURCE -typedef int pid_t; -# undef WEXITSTATUS -# undef WIFEXITED -# undef WIFSTOPPED -# undef WTERMSIG -# endif /* ! _POSIX_SOURCE */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/etc/sendmail/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/sendmail/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ - -# ifdef TCPWRAPPERS -# ifndef HASUNSETENV -# define HASUNSETENV 1 -# endif /* ! HASUNSETENV */ -# undef NEEDPUTENV -# endif /* TCPWRAPPERS */ - -#endif /* NeXT */ - -/* -** Apple Rhapsody -** Contributed by Wilfredo Sanchez <wsanchez@apple.com> -** -** Also used for Apple Darwin support. -*/ - -#if defined(DARWIN) -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASFLOCK 1 /* has flock(2) syscall */ -# define HASUNAME 1 /* has uname(2) syscall */ -# define HASUNSETENV 1 -# define HASSETSID 1 /* has the setsid(2) POSIX syscall */ -# define HASINITGROUPS 1 -# define HASSETVBUF 1 -# define HASSETREUID 1 -# define USESETEUID 1 /* has usable seteuid(2) call */ -# define HASLSTAT 1 -# define HASSETRLIMIT 1 -# define HASWAITPID 1 -# define HASSTRERROR 1 /* has strerror(3) */ -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# define HASSTRERROR 1 /* has strerror(3) */ -# define HASGETDTABLESIZE 1 -# define HASGETUSERSHELL 1 -# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ -# define BSD4_4_SOCKADDR /* has sa_len */ -# define NETLINK 1 /* supports AF_LINK */ -# define HAS_ST_GEN 1 /* has st_gen field in stat struct */ -# define GIDSET_T gid_t -# define LA_TYPE LA_SUBR /* use getloadavg(3) */ -# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ -# define SPT_TYPE SPT_PSSTRINGS -# define SPT_PADCHAR '\0' /* pad process title with nulls */ -# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ -#endif /* DARWIN */ - - -/* -** 4.4 BSD -** -** See also BSD defines. -*/ - -#if defined(BSD4_4) && !defined(__bsdi__) && !defined(__GNU__) -# include <paths.h> -# define HASUNSETENV 1 /* has unsetenv(3) call */ -# define USESETEUID 1 /* has usable seteuid(2) call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# define HASSTRERROR 1 /* has strerror(3) */ -# define HAS_ST_GEN 1 /* has st_gen field in stat struct */ -# include <sys/cdefs.h> -# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ -# define BSD4_4_SOCKADDR /* has sa_len */ -# define NEED_PRINTF_PERCENTQ 1 /* doesn't have %lld */ -# define NETLINK 1 /* supports AF_LINK */ -# ifndef LA_TYPE -# define LA_TYPE LA_SUBR -# endif /* ! LA_TYPE */ -# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ -# define SPT_TYPE SPT_PSSTRINGS /* use PS_STRINGS pointer */ -#endif /* defined(BSD4_4) && !defined(__bsdi__) && !defined(__GNU__) */ - - -/* -** BSD/OS (was BSD/386) (all versions) -** From Tony Sanders, BSDI -*/ - -#ifdef __bsdi__ -# include <paths.h> -# define HASUNSETENV 1 /* has the unsetenv(3) call */ -# define HASSETREUID 0 /* BSD-OS has broken setreuid(2) emulation */ -# define HASSETSID 1 /* has the setsid(2) POSIX syscall */ -# define USESETEUID 1 /* has usable seteuid(2) call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASFCHOWN 1 /* has fchown(2) syscall */ -# define HASSETLOGIN 1 /* has setlogin(2) */ -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# define HASUNAME 1 /* has uname(2) syscall */ -# define HASSTRERROR 1 /* has strerror(3) */ -# define HAS_ST_GEN 1 /* has st_gen field in stat struct */ -# include <sys/cdefs.h> -# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ -# define BSD4_4_SOCKADDR /* has sa_len */ -# define NETLINK 1 /* supports AF_LINK */ -# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ -# ifndef LA_TYPE -# define LA_TYPE LA_SUBR -# endif /* ! LA_TYPE */ -# define GIDSET_T gid_t -# define QUAD_T quad_t -# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312 - /* version 1.1 or later */ -# undef SPT_TYPE -# define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ -# else /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312 */ - /* version 1.0 or earlier */ -# define SPT_PADCHAR '\0' /* pad process title with nulls */ -# endif /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312 */ -# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199701 /* on 3.x */ -# define HASSETUSERCONTEXT 1 /* has setusercontext */ -# endif /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199701 */ -# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199910 /* on 4.x */ -# define HASURANDOMDEV 1 /* has /dev/urandom(4) */ -# endif /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199910 */ -#endif /* __bsdi__ */ - - -/* -** QNX 4.2x -** Contributed by Glen McCready <glen@qnx.com>. -** -** Should work with all versions of QNX. -*/ - -#if defined(__QNX__) -# include <unix.h> -# include <sys/select.h> -# undef NGROUPS_MAX -# define HASSETSID 1 /* has the setsid(2) POSIX syscall */ -# define USESETEUID 1 /* has usable seteuid(2) call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */ -# define HASSETREUID 1 /* has setreuid(2) call */ -# define HASSTRERROR 1 /* has strerror(3) */ -# define HASFLOCK 0 -# undef HASINITGROUPS /* has initgroups(3) call */ -# define NEEDGETOPT 1 /* use sendmail's getopt */ -# define IP_SRCROUTE 1 /* can check IP source routing */ -# define TZ_TYPE TZ_TMNAME /* use tmname variable */ -# define GIDSET_T gid_t -# define LA_TYPE LA_ZERO -# define SFS_TYPE SFS_NONE -# define SPT_TYPE SPT_REUSEARGV -# define SPT_PADCHAR '\0' /* pad process title with nulls */ -# define HASGETUSERSHELL 0 -# define E_PSEUDOBASE 512 -# define _FILE_H_INCLUDED -#endif /* defined(__QNX__) */ - - -/* -** FreeBSD / NetBSD / OpenBSD (all architectures, all versions) -** -** 4.3BSD clone, closer to 4.4BSD for FreeBSD 1.x and NetBSD 0.9x -** 4.4BSD-Lite based for FreeBSD 2.x and NetBSD 1.x -** -** See also BSD defines. -*/ - -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -# include <paths.h> -# define HASUNSETENV 1 /* has unsetenv(3) call */ -# define HASSETSID 1 /* has the setsid(2) POSIX syscall */ -# define USESETEUID 1 /* has usable seteuid(2) call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASFCHOWN 1 /* fchown(2) */ -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# define HASUNAME 1 /* has uname(2) syscall */ -# define HASSTRERROR 1 /* has strerror(3) */ -# define HAS_ST_GEN 1 /* has st_gen field in stat struct */ -# define NEED_PRINTF_PERCENTQ 1 /* doesn't have %lld */ -# include <sys/cdefs.h> -# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ -# define BSD4_4_SOCKADDR /* has sa_len */ -# define NETLINK 1 /* supports AF_LINK */ -# define SAFENFSPATHCONF 1 /* pathconf(2) pessimizes on NFS filesystems */ -# define GIDSET_T gid_t -# define QUAD_T unsigned long long -# define SFIO_STDIO_COMPAT 1 /* can use RES_DEBUG */ -# ifndef LA_TYPE -# define LA_TYPE LA_SUBR -# endif /* ! LA_TYPE */ -# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */ -# if defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1) -# undef SPT_TYPE -# define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ -# endif /* defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1) */ -# if defined(__NetBSD__) && ((__NetBSD_Version__ > 102070000) || (NetBSD1_2 > 8) || defined(NetBSD1_4) || defined(NetBSD1_3)) -# define HASURANDOMDEV 1 /* has /dev/urandom(4) */ -# endif /* defined(__NetBSD__) && ((__NetBSD_Version__ > 102070000) || (NetBSD1_2 > 8) || defined(NetBSD1_4) || defined(NetBSD1_3)) */ -# if defined(__FreeBSD__) -# define HASSETLOGIN 1 /* has setlogin(2) */ -# if __FreeBSD_version >= 227001 -# define HASSRANDOMDEV 1 /* has srandomdev(3) */ -# define HASURANDOMDEV 1 /* has /dev/urandom(4) */ -# endif /* __FreeBSD_version >= 227001 */ -# undef SPT_TYPE -# if __FreeBSD__ >= 2 -# include <osreldate.h> -# if __FreeBSD_version >= 199512 /* 2.2-current when it appeared */ -# include <libutil.h> -# define SPT_TYPE SPT_BUILTIN -# endif /* __FreeBSD_version >= 199512 */ -# if __FreeBSD_version >= 222000 /* 2.2.2-release and later */ -# define HASSETUSERCONTEXT 1 /* BSDI-style login classes */ -# endif /* __FreeBSD_version >= 222000 */ -# if __FreeBSD_version >= 330000 /* 3.3.0-release and later */ -# ifndef HASSTRL -# define HASSTRL 1 /* has strlc{py,at}(3) functions */ -# endif /* HASSTRL */ -# endif /* __FreeBSD_version >= 330000 */ -# define USESYSCTL 1 /* use sysctl(3) for getting ncpus */ -# include <sys/sysctl.h> -# endif /* __FreeBSD__ >= 2 */ -# ifndef SPT_TYPE -# define SPT_TYPE SPT_REUSEARGV -# define SPT_PADCHAR '\0' /* pad process title with nulls */ -# endif /* ! SPT_TYPE */ -# endif /* defined(__FreeBSD__) */ -# if defined(__OpenBSD__) -# undef SPT_TYPE -# define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ -# define HASSETLOGIN 1 /* has setlogin(2) */ -# define HASSETREUID 0 /* OpenBSD has broken setreuid(2) emulation */ -# define HASURANDOMDEV 1 /* has /dev/urandom(4) */ -# if OpenBSD < 199912 -# define HASSTRL 0 /* strlcat(3) is broken in 2.5 and earlier */ -# else /* OpenBSD < 199912 */ -# define HASSTRL 1 /* has strlc{py,at}(3) functions */ -# if OpenBSD >= 200006 -# define HASSRANDOMDEV 1 /* has srandomdev(3) */ -# endif -# if OpenBSD >= 200012 -# define HASSETUSERCONTEXT 1 /* BSDI-style login classes */ -# endif -# endif /* OpenBSD < 199912 */ -# endif /* defined(__OpenBSD__) */ -#endif /* defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) */ - - -/* -** Mach386 -** -** For mt Xinu's Mach386 system. -*/ - -#if defined(MACH) && defined(i386) && !defined(__GNU__) -# define MACH386 1 -# define HASUNSETENV 1 /* has unsetenv(3) call */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# ifndef HASFLOCK -# define HASFLOCK 1 /* has flock(2) call */ -# endif /* ! HASFLOCK */ -# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ -# define NEEDSTRTOL 1 /* need the strtol() function */ -# define setpgid setpgrp -# ifndef LA_TYPE -# define LA_TYPE LA_FLOAT -# endif /* ! LA_TYPE */ -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# undef HASSETVBUF /* don't actually have setvbuf(3) */ -# undef WEXITSTATUS -# undef WIFEXITED -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -#endif /* defined(MACH) && defined(i386) && !defined(__GNU__) */ - - - -/* -** GNU OS (hurd) -** Largely BSD & posix compatible. -** Port contributed by Miles Bader <miles@gnu.ai.mit.edu>. -** Updated by Mark Kettenis <kettenis@wins.uva.nl>. -*/ - -#if defined(__GNU__) && !defined(NeXT) -# include <paths.h> -# define HASFCHMOD 1 /* has fchmod(2) call */ -# define HASFCHOWN 1 /* has fchown(2) call */ -# define HASUNAME 1 /* has uname(2) call */ -# define HASUNSETENV 1 /* has unsetenv(3) call */ -# define HAS_ST_GEN 1 /* has st_gen field in stat struct */ -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# define HASSTRERROR 1 /* has strerror(3) */ -# define GIDSET_T gid_t -# define SOCKADDR_LEN_T socklen_t -# define SOCKOPT_LEN_T socklen_t -# if (__GLIBC__ == 2 && __GLIBC_MINOR__ > 1) || __GLIBC__ > 2 -# define LA_TYPE LA_SUBR -# else -# define LA_TYPE LA_MACH - /* GNU uses mach[34], which renames some rpcs from mach2.x. */ -# define host_self mach_host_self -# endif -# define SFS_TYPE SFS_STATFS -# define SPT_TYPE SPT_CHANGEARGV -# define ERRLIST_PREDEFINED 1 /* don't declare sys_errlist */ -# define BSD4_4_SOCKADDR 1 /* has sa_len */ -# define SIOCGIFCONF_IS_BROKEN 1 /* SIOCGFCONF doesn't work */ -# define HAS_IN_H 1 /* GNU has netinet/in.h. */ -/* GNU has no MAXPATHLEN; ideally the code should be changed to not use it. */ -# define MAXPATHLEN 2048 -#endif /* defined(__GNU__) && !defined(NeXT) */ - -/* -** 4.3 BSD -- this is for very old systems -** -** Should work for mt Xinu MORE/BSD and Mips UMIPS-BSD 2.1. -** -** You'll also have to install a new resolver library. -** I don't guarantee that support for this environment is complete. -*/ - -#if defined(oldBSD43) || defined(MORE_BSD) || defined(umipsbsd) -# define NEEDVPRINTF 1 /* need a replacement for vprintf(3) */ -# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ -# define ARBPTR_T char * -# define setpgid setpgrp -# ifndef LA_TYPE -# define LA_TYPE LA_FLOAT -# endif /* ! LA_TYPE */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -# undef WEXITSTATUS -# undef WIFEXITED -typedef short pid_t; -#endif /* defined(oldBSD43) || defined(MORE_BSD) || defined(umipsbsd) */ - - -/* -** SCO Unix -** -** This includes three parts: -** -** The first is for SCO OpenServer 5. -** (Contributed by Keith Reynolds <keithr@sco.COM>). -** -** SCO OpenServer 5 has a compiler version number macro, -** which we can use to figure out what version we're on. -** This may have to change in future releases. -** -** The second is for SCO UNIX 3.2v4.2/Open Desktop 3.0. -** (Contributed by Philippe Brand <phb@colombo.telesys-innov.fr>). -** -** The third is for SCO UNIX 3.2v4.0/Open Desktop 2.0 and earlier. -*/ - -/* SCO OpenServer 5 */ -#if _SCO_DS >= 1 -# include <paths.h> -# define SIOCGIFNUM_IS_BROKEN 1 /* SIOCGIFNUM returns bogus value */ -# define HASSNPRINTF 1 /* has snprintf(3) call */ -# define HASFCHMOD 1 /* has fchmod(2) call */ -# define HASFCHOWN 1 /* has fchown(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 /* ! LA_TYPE */ -# define _PATH_AVENRUN "/dev/table/avenrun" -# ifndef _SCO_unix_4_2 -# define _SCO_unix_4_2 -# else /* ! _SCO_unix_4_2 */ -# define SOCKADDR_LEN_T size_t /* e.g., arg#3 to accept, getsockname */ -# define SOCKOPT_LEN_T size_t /* arg#5 to getsockopt */ -# endif /* ! _SCO_unix_4_2 */ -#endif /* _SCO_DS >= 1 */ - -/* 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_4_2 */ - -/* SCO UNIX 3.2v4.0 Open Desktop 2.0 and earlier */ -#ifdef _SCO_unix_ -# include <sys/stream.h> /* needed for IP_SRCROUTE */ -# define SYSTEM5 1 /* include all the System V defines */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# define NOFTRUNCATE 0 /* has (simulated) ftruncate call */ -# define USE_SIGLONGJMP 1 /* sigsetjmp needed for signal handling */ -# define MAXPATHLEN PATHSIZE -# define SFS_TYPE SFS_4ARGS /* use <sys/statfs.h> 4-arg impl */ -# define SFS_BAVAIL f_bfree /* alternate field name */ -# define SPT_TYPE SPT_SCO /* write kernel u. area */ -# define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */ -# define UID_T uid_t -# define GID_T gid_t -# define GIDSET_T gid_t -# define _PATH_UNIX "/unix" -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ - -/* stuff fixed in later releases */ -# ifndef _SCO_unix_4_2 -# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ -# endif /* ! _SCO_unix_4_2 */ - -# 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 /* ! _SCO_DS */ - -#endif /* _SCO_unix_ */ - - -/* -** ISC (SunSoft) Unix. -** -** Contributed by J.J. Bailey <jjb@jagware.bcc.com> -*/ - -#ifdef ISC_UNIX -# include <net/errno.h> -# include <sys/stream.h> /* needed for IP_SRCROUTE */ -# include <sys/bsdtypes.h> -# define SYSTEM5 1 /* include all the System V defines */ -# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# define HASSETREUID 1 /* has setreuid(2) call */ -# define NEEDFSYNC 1 /* needs the fsync(2) call stub */ -# define NETUNIX 0 /* no unix domain socket support */ -# define MAXPATHLEN 1024 -# define LA_TYPE LA_SHORT -# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */ -# define SFS_BAVAIL f_bfree /* alternate field name */ -# define _PATH_UNIX "/unix" -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -#endif /* ISC_UNIX */ - - -/* -** Altos System V (5.3.1) -** Contributed by Tim Rice <tim@trr.metro.net>. -*/ - -#ifdef ALTOS_SYSTEM_V -# include <sys/stream.h> -# include <limits.h> -# define SYSTEM5 1 /* include all the System V defines */ -# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# define WAITUNION 1 /* use "union wait" as wait argument type */ -# define NEEDFSYNC 1 /* no fsync(2) in system library */ -# define NEEDSTRSTR 1 /* need emulation of the strstr(3) call */ -# define NOFTRUNCATE 1 /* do not have ftruncate(2) */ -# define MAXPATHLEN PATH_MAX -# define LA_TYPE LA_SHORT -# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */ -# define SFS_BAVAIL f_bfree /* alternate field name */ -# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */ -# define NETUNIX 0 /* no unix domain socket support */ -# undef WIFEXITED -# undef WEXITSTATUS -# define strtoul strtol /* gcc library bogosity */ - -typedef unsigned short uid_t; -typedef unsigned short gid_t; -typedef short pid_t; -typedef unsigned long mode_t; - -/* some stuff that should have been in the include files */ -extern char *malloc(); -extern struct passwd *getpwent(); -extern struct passwd *getpwnam(); -extern struct passwd *getpwuid(); -extern char *getenv(); -extern struct group *getgrgid(); -extern struct group *getgrnam(); - -#endif /* ALTOS_SYSTEM_V */ - - -/* -** ConvexOS 11.0 and later -** -** "Todd C. Miller" <millert@mroe.cs.colorado.edu> claims this -** works on 9.1 as well. -** -** ConvexOS 11.5 and later, should work on 11.0 as defined. -** For pre-ConvexOOS 11.0, define NEEDGETOPT, undef IDENTPROTO -** -** Eric Schnoebelen (eric@cirr.com) For CONVEX Computer Corp. -** (now the CONVEX Technologies Center of Hewlett Packard) -*/ - -#ifdef _CONVEX_SOURCE -# define HASGETDTABLESIZE 1 /* has getdtablesize(2) */ -# define HASINITGROUPS 1 /* has initgroups(3) */ -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASSETSID 1 /* has POSIX setsid(2) call */ -# define HASUNSETENV 1 /* has unsetenv(3) */ -# define HASFLOCK 1 /* has flock(2) */ -# define HASSETRLIMIT 1 /* has setrlimit(2) */ -# define HASSETREUID 1 /* has setreuid(2) */ -# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_error=0 */ -# define NEEDPUTENV 1 /* needs putenv (written in terms of setenv) */ -# define NEEDGETOPT 0 /* need replacement for getopt(3) */ -# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */ -# define LA_TYPE LA_FLOAT -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef S_IREAD -# define S_IREAD _S_IREAD -# define S_IWRITE _S_IWRITE -# define S_IEXEC _S_IEXEC -# define S_IFMT _S_IFMT -# define S_IFCHR _S_IFCHR -# define S_IFBLK _S_IFBLK -# endif /* ! S_IREAD */ -# ifndef TZ_TYPE -# define TZ_TYPE TZ_TIMEZONE -# endif /* ! TZ_TYPE */ -# ifndef IDENTPROTO -# define IDENTPROTO 1 -# endif /* ! IDENTPROTO */ -# ifndef SHARE_V1 -# define SHARE_V1 1 /* version 1 of the fair share scheduler */ -# endif /* ! SHARE_V1 */ -# if !defined(__GNUC__ ) -# define UID_T int /* GNUC gets it right, ConvexC botches */ -# define GID_T int /* GNUC gets it right, ConvexC botches */ -# endif /* !defined(__GNUC__ ) */ -# if SECUREWARE -# define FORK fork /* SecureWare wants the real fork! */ -# else /* SECUREWARE */ -# define FORK vfork /* the rest of the OS versions don't care */ -# endif /* SECUREWARE */ -#endif /* _CONVEX_SOURCE */ - - -/* -** RISC/os 4.52 -** -** Gives a ton of warning messages, but otherwise compiles. -*/ - -#ifdef RISCOS - -# define HASUNSETENV 1 /* has unsetenv(3) call */ -# ifndef HASFLOCK -# define HASFLOCK 1 /* has flock(2) call */ -# endif /* ! HASFLOCK */ -# define WAITUNION 1 /* use "union wait" as wait argument type */ -# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ -# define NEEDPUTENV 1 /* need putenv(3) call */ -# define NEEDSTRSTR 1 /* need emulation of the strstr(3) call */ -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# define LA_TYPE LA_INT -# define LA_AVENRUN "avenrun" -# define _PATH_UNIX "/unix" -# undef WIFEXITED - -# define setpgid setpgrp - -typedef int pid_t; -# define SIGFUNC_DEFINED -# define SIGFUNC_RETURN (0) -# define SIGFUNC_DECL int -typedef int (*sigfunc_t)(); -extern char *getenv(); -extern void *malloc(); - -/* added for RISC/os 4.01...which is dumber than 4.50 */ -# ifdef RISCOS_4_0 -# ifndef ARBPTR_T -# define ARBPTR_T char * -# endif /* ! ARBPTR_T */ -# undef HASFLOCK -# define HASFLOCK 0 -# endif /* RISCOS_4_0 */ - -# include <sys/time.h> - -#endif /* RISCOS */ - - -/* -** Linux 0.99pl10 and above... -** -** Thanks to, in reverse order of contact: -** -** John Kennedy <warlock@csuchico.edu> -** Andrew Pam <avatar@aus.xanadu.com> -** Florian La Roche <rzsfl@rz.uni-sb.de> -** Karl London <karl@borg.demon.co.uk> -** -** Last compiled against: [07/21/98 @ 11:47:34 AM (Tuesday)] -** sendmail 8.9.1 bind-8.1.2 db-2.4.14 -** gcc-2.8.1 glibc-2.0.94 linux-2.1.109 -** -** NOTE: Override HASFLOCK as you will but, as of 1.99.6, mixed-style -** file locking is no longer allowed. In particular, make sure -** your DBM library and sendmail are both using either flock(2) -** *or* fcntl(2) file locking, but not both. -*/ - -#ifdef __linux__ -# include <linux/version.h> -# if !defined(KERNEL_VERSION) /* not defined in 2.0.x kernel series */ -# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -# endif /* KERNEL_VERSION */ -# define BSD 1 /* include BSD defines */ -# define USESETEUID 0 /* Have it due to POSIX, but doesn't work */ -# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASUNSETENV 1 /* has unsetenv(3) call */ -# ifndef HASSNPRINTF -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# endif /* ! HASSNPRINTF */ -# define ERRLIST_PREDEFINED /* don't declare sys_errlist */ -# define GIDSET_T gid_t /* from <linux/types.h> */ -# define HASGETUSERSHELL 0 /* getusershell(3) broken in Slackware 2.0 */ -# ifndef IP_SRCROUTE -# define IP_SRCROUTE 0 /* linux <= 1.2.8 doesn't support IP_OPTIONS */ -# endif /* ! IP_SRCROUTE */ -# ifndef HAS_IN_H -# define HAS_IN_H 1 /* use netinet/in.h */ -# endif /* ! HAS_IN_H */ -# define USE_SIGLONGJMP 1 /* sigsetjmp needed for signal handling */ -# ifndef HASFLOCK -# if LINUX_VERSION_CODE < 66399 -# define HASFLOCK 0 /* flock(2) is broken after 0.99.13 */ -# else /* LINUX_VERSION_CODE < 66399 */ -# define HASFLOCK 1 /* flock(2) fixed after 1.3.95 */ -# endif /* LINUX_VERSION_CODE < 66399 */ -# endif /* ! HASFLOCK */ -# ifndef LA_TYPE -# define LA_TYPE LA_PROCSTR -# endif /* ! LA_TYPE */ -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() impl */ -# define SPT_PADCHAR '\0' /* pad process title with nulls */ -# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0)) -# ifndef HASURANDOMDEV -# define HASURANDOMDEV 1 /* 2.0 (at least) has linux/drivers/char/random.c */ -# endif /* ! HASURANDOMDEV */ -# endif /* LINUX_VERSION_CODE */ -# ifndef TZ_TYPE -# define TZ_TYPE TZ_NONE /* no standard for Linux */ -# endif /* ! TZ_TYPE */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/var/run/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -# include <sys/sysmacros.h> -# undef atol /* wounded in <stdlib.h> */ -# if NETINET6 - /* - ** Linux doesn't have a good way to tell userland what interfaces are - ** IPv6-capable. Therefore, the BIND resolver can not determine if there - ** are IPv6 interfaces to honor AI_ADDRCONFIG. Unfortunately, it assumes - ** that none are present. (Excuse the macro name ADDRCONFIG_IS_BROKEN.) - */ -# define ADDRCONFIG_IS_BROKEN 1 - - /* - ** Indirectly included from glibc's <feature.h>. IPv6 support is native - ** in 2.1 and later, but the APIs appear before the functions. - */ -# if defined(__GLIBC__) && defined(__GLIBC_MINOR__) -# define GLIBC_VERSION ((__GLIBC__ << 8) + __GLIBC_MINOR__) -# if (GLIBC_VERSION >= 0x201) -# undef IPPROTO_ICMPV6 /* linux #defines, glibc enums */ -# else /* (GLIBC_VERSION >= 0x201) */ -# include <linux/in6.h> /* IPv6 support */ -# endif /* (GLIBC_VERSION >= 0x201) */ -# if (GLIBC_VERSION >= 0x201 && !defined(NEEDSGETIPNODE)) - /* Have APIs in <netdb.h>, but no support in glibc */ -# define NEEDSGETIPNODE 1 -# endif /* (GLIBC_VERSION >= 0x201 && !defined(NEEDSGETIPNODE)) */ -# undef GLIBC_VERSION -# endif /* defined(__GLIBC__) && defined(__GLIBC_MINOR__) */ -# endif /* NETINET6 */ -# ifndef HASFCHOWN -# define HASFCHOWN 1 /* fchown(2) */ -# endif /* ! HASFCHOWN */ -#endif /* __linux__ */ - - -/* -** DELL SVR4 Issue 2.2, and others -** From Kimmo Suominen <kim@grendel.lut.fi> -** -** It's on #ifdef DELL_SVR4 because Solaris also gets __svr4__ -** defined, and the definitions conflict. -** -** Peter Wemm <peter@perth.DIALix.oz.au> claims that the setreuid -** trick works on DELL 2.2 (SVR4.0/386 version 4.0) and ESIX 4.0.3A -** (SVR4.0/386 version 3.0). -*/ - -#ifdef DELL_SVR4 - /* no changes necessary */ - /* see general __svr4__ defines below */ -#endif /* DELL_SVR4 */ - - -/* -** Apple A/UX 3.0 -*/ - -#ifdef _AUX_SOURCE -# include <sys/sysmacros.h> -# define BSD /* has BSD routines */ -# define HASSETRLIMIT 0 /* ... but not setrlimit(2) */ -# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */ -# define BOGUS_O_EXCL 1 /* exclusive open follows symlinks */ -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASSETVBUF 1 /* has setvbuf(3) in libc */ -# define HASSTRERROR 1 /* has strerror(3) */ -# define SIGFUNC_DEFINED /* sigfunc_t already defined */ -# define SIGFUNC_RETURN /* POSIX-mode */ -# define SIGFUNC_DECL void /* POSIX-mode */ -# define ERRLIST_PREDEFINED 1 -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -# ifndef LA_TYPE -# define LA_TYPE LA_INT -# define FSHIFT 16 -# endif /* ! LA_TYPE */ -# define LA_AVENRUN "avenrun" -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# define TZ_TYPE TZ_TZNAME -# ifndef _PATH_UNIX -# define _PATH_UNIX "/unix" /* should be in <paths.h> */ -# endif /* ! _PATH_UNIX */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# undef WIFEXITED -# undef WEXITSTATUS -#endif /* _AUX_SOURCE */ - - -/* -** Encore UMAX V -** -** Not extensively tested. -*/ - -#ifdef UMAXV -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ -# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */ -# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ -# define MAXPATHLEN PATH_MAX -extern struct passwd *getpwent(), *getpwnam(), *getpwuid(); -extern struct group *getgrent(), *getgrnam(), *getgrgid(); -# undef WIFEXITED -# undef WEXITSTATUS -#endif /* UMAXV */ - - -/* -** Stardent Titan 3000 running TitanOS 4.2. -** -** Must be compiled in "cc -43" mode. -** -** From Kate Hedstrom <kate@ahab.rutgers.edu>. -** -** Note the tweaking below after the BSD defines are set. -*/ - -#ifdef titan -# define setpgid setpgrp -typedef int pid_t; -# undef WIFEXITED -# undef WEXITSTATUS -#endif /* titan */ - - -/* -** Sequent DYNIX 3.2.0 -** -** From Jim Davis <jdavis@cs.arizona.edu>. -*/ - -#ifdef sequent - -# define BSD 1 -# define HASUNSETENV 1 -# define BSD4_3 1 /* to get signal() in conf.c */ -# define WAITUNION 1 -# define LA_TYPE LA_FLOAT -# ifdef _POSIX_VERSION -# undef _POSIX_VERSION /* set in <unistd.h> */ -# endif /* _POSIX_VERSION */ -# undef HASSETVBUF /* don't actually have setvbuf(3) */ -# define setpgid setpgrp - -/* Have to redefine WIFEXITED to take an int, to work with waitfor() */ -# undef WIFEXITED -# define WIFEXITED(s) (((union wait*)&(s))->w_stopval != WSTOPPED && \ - ((union wait*)&(s))->w_termsig == 0) -# define WEXITSTATUS(s) (((union wait*)&(s))->w_retcode) -typedef int pid_t; -# define isgraph(c) (isprint(c) && (c != ' ')) - -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ - -# ifndef _PATH_UNIX -# define _PATH_UNIX "/dynix" -# endif /* ! _PATH_UNIX */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -#endif /* sequent */ - - -/* -** Sequent DYNIX/ptx v2.0 (and higher) -** -** For DYNIX/ptx v1.x, undefine HASSETREUID. -** -** From Tim Wright <timw@sequent.com>. -** Update from Jack Woolley <jwoolley@sctcorp.com>, 26 Dec 1995, -** for DYNIX/ptx 4.0.2. -*/ - -#ifdef _SEQUENT_ -# include <sys/stream.h> -# define SYSTEM5 1 /* include all the System V defines */ -# define HASSETSID 1 /* has POSIX setsid(2) call */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASSETREUID 1 /* has setreuid(2) call */ -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# define GIDSET_T gid_t -# define LA_TYPE LA_INT -# define SFS_TYPE SFS_STATFS /* use <sys/statfs.h> statfs() impl */ -# define SPT_TYPE SPT_NONE /* don't use setproctitle */ -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -#endif /* _SEQUENT_ */ - - -/* -** Cray Unicos -** -** Ported by David L. Kensiski, Sterling Sofware <kensiski@nas.nasa.gov> -*/ - -#ifdef UNICOS -# define SYSTEM5 1 /* include all the System V defines */ -# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ -# define MAXPATHLEN PATHSIZE -# define LA_TYPE LA_ZERO -# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ -# define SFS_BAVAIL f_bfree /* alternate field name */ -#endif /* UNICOS */ - - -/* -** Apollo DomainOS -** -** From Todd Martin <tmartint@tus.ssi1.com> & Don Lewis <gdonl@gv.ssi1.com> -** -** 15 Jan 1994; updated 2 Aug 1995 -** -*/ - -#ifdef apollo -# define HASSETREUID 1 /* has setreuid(2) call */ -# define HASINITGROUPS 1 /* has initgroups(2) call */ -# define IP_SRCROUTE 0 /* does not have <netinet/ip_var.h> */ -# define SPT_TYPE SPT_NONE /* don't use setproctitle */ -# define LA_TYPE LA_SUBR /* use getloadavg.c */ -# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ -# define SFS_BAVAIL f_bfree /* alternate field name */ -# define TZ_TYPE TZ_TZNAME -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -# undef S_IFSOCK /* S_IFSOCK and S_IFIFO are the same */ -# undef S_IFIFO -# define S_IFIFO 0010000 -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -# define RLIMIT_NEEDS_SYS_TIME_H 1 -# if defined(NGROUPS_MAX) && !NGROUPS_MAX -# undef NGROUPS_MAX -# endif /* defined(NGROUPS_MAX) && !NGROUPS_MAX */ -#endif /* apollo */ - -/* -** System V Rel 5.x (a.k.a Unixware7 w/o BSD-Compatibility Libs ie. native) -** -** Contributed by Paul Gampe <paulg@apnic.net> -*/ - -#ifdef __svr5__ -# include <sys/mkdev.h> -# define __svr4__ -# define SYS5SIGNALS 1 -# define HASFCHOWN 1 /* has fchown(2) call */ -# define HASSETSID 1 -# define HASSNPRINTF 1 -# define HASSETREUID 1 -# define HASWAITPID 1 -# define HASGETDTABLESIZE 1 -# define GIDSET_T gid_t -# define SOCKADDR_LEN_T size_t -# define SOCKOPT_LEN_T size_t -# ifndef _PATH_UNIX -# define _PATH_UNIX "/stand/unix" -# endif /* ! _PATH_UNIX */ -# define SPT_PADCHAR '\0' /* pad process title with nulls */ -# ifndef SYSLOG_BUFSIZE -# define SYSLOG_BUFSIZE 1024 /* unsure */ -# endif /* SYSLOG_BUFSIZE */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/etc/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -# undef offsetof /* avoid stddefs.h, sys/sysmacros.h conflict */ -#if !defined(SM_SET_H_ERRNO) && defined(_REENTRANT) -# define SM_SET_H_ERRNO(err) set_h_errno((err)) -#endif /* ! SM_SET_H_ERRNO && _REENTRANT */ -#endif /* __svr5__ */ - -/* ###################################################################### */ - -/* -** UnixWare 2.x -*/ - -#ifdef UNIXWARE2 -# define UNIXWARE 1 -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# undef offsetof /* avoid stddefs.h, sys/sysmacros.h conflict */ -#endif /* UNIXWARE2 */ - - -/* -** UnixWare 1.1.2. -** -** Updated by Petr Lampa <lampa@fee.vutbr.cz>. -** From Evan Champion <evanc@spatial.synapse.org>. -*/ - -#ifdef UNIXWARE -# include <sys/mkdev.h> -# define SYSTEM5 1 -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# define HASSETREUID 1 -# define HASSETSID 1 -# define HASINITGROUPS 1 -# define GIDSET_T gid_t -# define SLEEP_T unsigned -# define SFS_TYPE SFS_STATVFS -# define LA_TYPE LA_ZERO -# undef WIFEXITED -# undef WEXITSTATUS -# ifndef _PATH_UNIX -# define _PATH_UNIX "/unix" -# endif /* ! _PATH_UNIX */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -# define SYSLOG_BUFSIZE 128 -#endif /* UNIXWARE */ - - -/* -** Intergraph CLIX 3.1 -** -** From Paul Southworth <pauls@locust.cic.net> -*/ - -#ifdef CLIX -# define SYSTEM5 1 /* looks like System V */ -# ifndef HASGETUSERSHELL -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# endif /* ! HASGETUSERSHELL */ -# define DEV_BSIZE 512 /* device block size not defined */ -# define GIDSET_T gid_t -# undef LOG /* syslog not available */ -# define NEEDFSYNC 1 /* no fsync in system library */ -# define GETSHORT _getshort -#endif /* CLIX */ - - -/* -** NCR MP-RAS 2.x (SysVr4) with Wollongong TCP/IP -** -** From Kevin Darcy <kevin@tech.mis.cfc.com>. -*/ - -#ifdef NCR_MP_RAS2 -# include <sys/sockio.h> -# define __svr4__ -# define IP_SRCROUTE 0 /* Something is broken with getsockopt() */ -# define SYSLOG_BUFSIZE 1024 -# define SPT_TYPE SPT_NONE -#endif /* NCR_MP_RAS2 */ - - -/* -** NCR MP-RAS 3.x (SysVr4) with STREAMware TCP/IP -** -** From Tom Moore <Tom.Moore@DaytonOH.NCR.COM> -*/ - -#ifdef NCR_MP_RAS3 -# define __svr4__ -# define HASFCHOWN 1 /* has fchown(2) call */ -# define SIOCGIFNUM_IS_BROKEN 1 /* SIOCGIFNUM has non-std interface */ -# define SO_REUSEADDR_IS_BROKEN 1 /* doesn't work if accept() fails */ -# define SYSLOG_BUFSIZE 1024 -# define SPT_TYPE SPT_NONE -# ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE -# define _XOPEN_SOURCE_EXTENDED 1 -# include <sys/resource.h> -# undef _XOPEN_SOURCE -# undef _XOPEN_SOURCE_EXTENDED -# endif /* ! _XOPEN_SOURCE */ -#endif /* NCR_MP_RAS3 */ - - -/* -** Tandem NonStop-UX SVR4 -** -** From Rick McCarty <mccarty@mpd.tandem.com>. -*/ - -#ifdef NonStop_UX_BXX -# define __svr4__ -#endif /* NonStop_UX_BXX */ - - -/* -** Hitachi 3050R/3050RX and 3500 Workstations running HI-UX/WE2. -** -** Tested for 1.04, 1.03 -** From Akihiro Hashimoto ("Hash") <hash@dominic.ipc.chiba-u.ac.jp>. -** -** Tested for 4.02, 6.10 and 7.10 -** From Motonori NAKAMURA <motonori@media.kyoto-u.ac.jp>. -*/ - -#if !defined(__hpux) && (defined(_H3050R) || defined(_HIUX_SOURCE)) -# define SYSTEM5 1 /* include all the System V defines */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define setreuid(r, e) setresuid(r, e, -1) -# define LA_TYPE LA_FLOAT -# define SPT_TYPE SPT_PSTAT -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# ifndef HASSETVBUF -# define HASSETVBUF /* HI-UX has no setlinebuf */ -# endif /* ! HASSETVBUF */ -# ifndef GIDSET_T -# define GIDSET_T gid_t -# endif /* ! GIDSET_T */ -# ifndef _PATH_UNIX -# define _PATH_UNIX "/HI-UX" -# endif /* ! _PATH_UNIX */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -# ifndef HASGETUSERSHELL -# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */ -# endif /* ! HASGETUSERSHELL */ -# define FDSET_CAST (int *) /* cast for fd_set parameters to select */ - -/* -** avoid m_flags conflict between Berkeley DB 1.85 db.h & sys/sysmacros.h -** on HIUX 3050 -*/ -# undef m_flags - -# ifdef __STDC__ -extern int syslog(int, char *, ...); -# else /* __STDC__ */ -extern int syslog(); -# endif /* __STDC__ */ - -#endif /* !defined(__hpux) && (defined(_H3050R) || defined(_HIUX_SOURCE)) */ - - -/* -** Amdahl UTS System V 2.1.5 (SVr3-based) -** -** From: Janet Jackson <janet@dialix.oz.au>. -*/ - -#ifdef _UTS -# include <sys/sysmacros.h> -# undef HASLSTAT /* has symlinks, but they cause problems */ -# define NEEDFSYNC 1 /* system fsync(2) fails on non-EFS filesys */ -# define SYS5SIGNALS 1 /* System V signal semantics */ -# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */ -# define HASUNAME 1 /* use System V uname(2) system call */ -# define HASINITGROUPS 1 /* has initgroups(3) function */ -# define HASSETVBUF 1 /* has setvbuf(3) function */ -# ifndef HASGETUSERSHELL -# define HASGETUSERSHELL 0 /* does not have getusershell(3) function */ -# endif /* ! HASGETUSERSHELL */ -# define GIDSET_T gid_t /* type of 2nd arg to getgroups(2) isn't int */ -# define LA_TYPE LA_ZERO /* doesn't have load average */ -# define SFS_TYPE SFS_4ARGS /* use 4-arg statfs() */ -# define SFS_BAVAIL f_bfree /* alternate field name */ -# define _PATH_UNIX "/unix" -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -#endif /* _UTS */ - -/* -** Cray Computer Corporation's CSOS -** -** From Scott Bolte <scott@craycos.com>. -*/ - -#ifdef _CRAYCOM -# define SYSTEM5 1 /* include all the System V defines */ -# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ -# define NEEDFSYNC 1 /* no fsync in system library */ -# define MAXPATHLEN PATHSIZE -# define LA_TYPE LA_ZERO -# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ -# define SFS_BAVAIL f_bfree /* alternate field name */ -# define _POSIX_CHOWN_RESTRICTED -1 -extern struct group *getgrent(), *getgrnam(), *getgrgid(); -#endif /* _CRAYCOM */ - - -/* -** Sony NEWS-OS 4.2.1R and 6.0.3 -** -** From Motonori NAKAMURA <motonori@cs.ritsumei.ac.jp>. -*/ - -#ifdef sony_news -# ifndef __svr4 - /* NEWS-OS 4.2.1R */ -# ifndef BSD -# define BSD /* has BSD routines */ -# endif /* ! BSD */ -# define HASUNSETENV 1 /* has unsetenv(2) call */ -# undef HASSETVBUF /* don't actually have setvbuf(3) */ -# define WAITUNION 1 /* use "union wait" as wait argument type */ -# define LA_TYPE LA_INT -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# ifndef HASFLOCK -# define HASFLOCK 1 /* has flock(2) call */ -# endif /* ! HASFLOCK */ -# define setpgid setpgrp -# undef WIFEXITED -# undef WEXITSTATUS -# define MODE_T int /* system include files have no mode_t */ -typedef int pid_t; -typedef int (*sigfunc_t)(); -# define SIGFUNC_DEFINED -# define SIGFUNC_RETURN (0) -# define SIGFUNC_DECL int - -# else /* ! __svr4 */ - /* NEWS-OS 6.0.3 with /bin/cc */ -# ifndef __svr4__ -# define __svr4__ /* use all System V Release 4 defines below */ -# endif /* ! __svr4__ */ -# define HASSETSID 1 /* has Posix setsid(2) call */ -# define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */ -# define LA_TYPE LA_READKSYM /* use MIOC_READKSYM ioctl */ -# ifndef SPT_TYPE -# define SPT_TYPE SPT_SYSMIPS /* use sysmips() (OS 6.0.2 or later) */ -# endif /* ! SPT_TYPE */ -# define GIDSET_T gid_t -# undef WIFEXITED -# undef WEXITSTATUS -# ifndef SYSLOG_BUFSIZE -# define SYSLOG_BUFSIZE 256 -# endif /* ! SYSLOG_BUFSIZE */ -# define _PATH_UNIX "/stand/unix" -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ - -# endif /* ! __svr4 */ -#endif /* sony_news */ - - -/* -** Omron LUNA/UNIOS-B 3.0, LUNA2/Mach and LUNA88K Mach -** -** From Motonori NAKAMURA <motonori@cs.ritsumei.ac.jp>. -*/ - -#ifdef luna -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -# define HASUNSETENV 1 /* has unsetenv(2) call */ -# define NEEDPUTENV 1 /* need putenv(3) call */ -# define NEEDGETOPT 1 /* need a replacement for getopt(3) */ -# define NEEDSTRSTR 1 /* need emulation of the strstr(3) call */ -# define WAITUNION 1 /* use "union wait" as wait argument type */ -# ifdef uniosb -# include <sys/time.h> -# define NEEDVPRINTF 1 /* need a replacement for vprintf(3) */ -# define LA_TYPE LA_INT -# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */ -# endif /* uniosb */ -# ifdef luna2 -# define LA_TYPE LA_SUBR -# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */ -# endif /* luna2 */ -# ifdef luna88k -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# define LA_TYPE LA_INT -# endif /* luna88k */ -# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */ -# define setpgid setpgrp -# undef WIFEXITED -# undef WEXITSTATUS -typedef int pid_t; -typedef int (*sigfunc_t)(); -# define SIGFUNC_DEFINED -# define SIGFUNC_RETURN (0) -# define SIGFUNC_DECL int -extern char *getenv(); -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -#endif /* luna */ - - -/* -** NEC EWS-UX/V 4.2 (with /usr/ucb/cc) -** -** From Motonori NAKAMURA <motonori@cs.ritsumei.ac.jp>. -*/ - -#if defined(nec_ews_svr4) || defined(_nec_ews_svr4) -# ifndef __svr4__ -# define __svr4__ /* use all System V Release 4 defines below */ -# endif /* ! __svr4__ */ -# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ -# define HASSETSID 1 /* has Posix setsid(2) call */ -# define LA_TYPE LA_READKSYM /* use MIOC_READSYM ioctl */ -# define SFS_TYPE SFS_USTAT /* use System V ustat(2) syscall */ -# define GIDSET_T gid_t -# undef WIFEXITED -# undef WEXITSTATUS -# define NAMELISTMASK 0x7fffffff /* mask for nlist() values */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -# ifndef SYSLOG_BUFSIZE -# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */ -# endif /* ! SYSLOG_BUFSIZE */ -#endif /* defined(nec_ews_svr4) || defined(_nec_ews_svr4) */ - - -/* -** Fujitsu/ICL UXP/DS (For the DS/90 Series) -** -** From Diego R. Lopez <drlopez@cica.es>. -** Additional changes from Fumio Moriya and Toshiaki Nomura of the -** Fujitsu Fresoftware group <dsfrsoft@oai6.yk.fujitsu.co.jp>. -*/ - -#ifdef __uxp__ -# include <arpa/nameser.h> -# include <sys/sysmacros.h> -# include <sys/mkdev.h> -# define __svr4__ -# define HASGETUSERSHELL 0 -# define HASFLOCK 0 -# if UXPDS == 10 -# define HASSNPRINTF 0 /* no snprintf(3) or vsnprintf(3) */ -# else /* UXPDS == 10 */ -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# endif /* UXPDS == 10 */ -# define _PATH_UNIX "/stand/unix" -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -#endif /* __uxp__ */ - -/* -** Pyramid DC/OSx -** -** From Earle Ake <akee@wpdiss1.wpafb.af.mil>. -*/ - -#ifdef DCOSx -# define GIDSET_T gid_t -# ifndef IDENTPROTO -# define IDENTPROTO 0 /* TCP/IP implementation is broken */ -# endif /* ! IDENTPROTO */ -#endif /* DCOSx */ - -/* -** Concurrent Computer Corporation Maxion -** -** From Donald R. Laster Jr. <laster@access.digex.net>. -*/ - -#ifdef __MAXION__ - -# include <sys/stream.h> -# define __svr4__ 1 /* SVR4.2MP */ -# define HASSETREUID 1 /* have setreuid(2) */ -# define HASLSTAT 1 /* have lstat(2) */ -# define HASSETRLIMIT 1 /* have setrlimit(2) */ -# define HASGETDTABLESIZE 1 /* have getdtablesize(2) */ -# define HASSNPRINTF 1 /* have snprintf(3) */ -# define HASGETUSERSHELL 1 /* have getusershell(3) */ -# define NOFTRUNCATE 1 /* do not have ftruncate(2) */ -# define SLEEP_T unsigned -# define SFS_TYPE SFS_STATVFS -# define SFS_BAVAIL f_bavail -# ifndef SYSLOG_BUFSIZE -# define SYSLOG_BUFSIZE 256 /* Use 256 bytes */ -# endif /* ! SYSLOG_BUFSIZE */ - -# undef WUNTRACED -# undef WIFEXITED -# undef WIFSIGNALED -# undef WIFSTOPPED -# undef WEXITSTATUS -# undef WTERMSIG -# undef WSTOPSIG - -#endif /* __MAXION__ */ - -/* -** Harris Nighthawk PowerUX (nh6000 box) -** -** Contributed by Bob Miorelli, Pratt & Whitney <miorelli@pweh.com> -*/ - -#ifdef _PowerUX -# ifndef __svr4__ -# define __svr4__ -# endif /* ! __svr4__ */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -# define SYSLOG_BUFSIZE 1024 -# define HASSNPRINTF 1 /* has snprintf(3) and vsnprintf(3) */ -# define LA_TYPE LA_ZERO -typedef struct msgb mblk_t; -# undef offsetof /* avoid stddefs.h and sys/sysmacros.h conflict */ -#endif /* _PowerUX */ - -/* -** Siemens Nixdorf Informationssysteme AG SINIX -** -** Contributed by Gerald Rinske <Gerald.Rinske@mch.sni.de> -** of Siemens Business Services VAS. -*/ -#ifdef sinix -# define HASRANDOM 0 /* has random(3) */ -# define SYSLOG_BUFSIZE 1024 -#endif /* sinix */ - -/* -** CRAY T3E -** -** Contributed by Manu Mahonen <mailadm@csc.fi> -** of Center for Scientific Computing. -*/ -#ifdef _CRAY -# define GET_IPOPT_DST(dst) *(struct in_addr *)&(dst) -#endif /* _CRAY */ - -/* -** Motorola 922, MC88110, UNIX SYSTEM V/88 Release 4.0 Version 4.3 -** -** Contributed by Sergey Rusanov <rsm@utfoms.udmnet.ru> -*/ - -#ifdef MOTO -# define HASFCHMOD 1 -# define HASSETRLIMIT 0 -# define HASSETSID 1 -# define HASSETREUID 1 -# define HASULIMIT 1 -# define HASWAITPID 1 -# define HASGETDTABLESIZE 1 -# define HASGETUSERSHELL 1 -# define IP_SRCROUTE 0 -# define IDENTPROTO 0 -# define RES_DNSRCH_VARIABLE _res_dnsrch -# define _PATH_UNIX "/unix" -# define _PATH_VENDOR_CF "/etc/sendmail.cf" -# define _PATH_SENDMAILPID "/var/run/sendmail.pid" -#endif /* MOTO */ - - -/********************************************************************** -** End of Per-Operating System defines -**********************************************************************/ -/********************************************************************** -** More general defines -**********************************************************************/ - -/* general BSD defines */ -#ifdef BSD -# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */ -# ifndef HASSETREUID -# define HASSETREUID 1 /* has setreuid(2) call */ -# endif /* ! HASSETREUID */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# ifndef IP_SRCROUTE -# define IP_SRCROUTE 1 /* can check IP source routing */ -# endif /* ! IP_SRCROUTE */ -# ifndef HASSETRLIMIT -# define HASSETRLIMIT 1 /* has setrlimit(2) call */ -# endif /* ! HASSETRLIMIT */ -# ifndef HASFLOCK -# define HASFLOCK 1 /* has flock(2) call */ -# endif /* ! HASFLOCK */ -# ifndef TZ_TYPE -# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone variable */ -# endif /* ! TZ_TYPE */ -#endif /* BSD */ - -/* general System V Release 4 defines */ -#ifdef __svr4__ -# define SYSTEM5 1 -# define USESETEUID 1 /* has usable seteuid(2) call */ -# define HASINITGROUPS 1 /* has initgroups(3) call */ -# define BSD_COMP 1 /* get BSD ioctl calls */ -# ifndef HASSETRLIMIT -# define HASSETRLIMIT 1 /* has setrlimit(2) call */ -# endif /* ! HASSETRLIMIT */ -# ifndef HASGETUSERSHELL -# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ -# endif /* ! HASGETUSERSHELL */ -# ifndef HASFCHMOD -# define HASFCHMOD 1 /* most (all?) SVr4s seem to have fchmod(2) */ -# endif /* ! HASFCHMOD */ - -# ifndef _PATH_UNIX -# define _PATH_UNIX "/unix" -# endif /* ! _PATH_UNIX */ -# ifndef _PATH_VENDOR_CF -# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf" -# endif /* ! _PATH_VENDOR_CF */ -# ifndef _PATH_SENDMAILPID -# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid" -# endif /* ! _PATH_SENDMAILPID */ -# ifndef SYSLOG_BUFSIZE -# define SYSLOG_BUFSIZE 128 -# endif /* ! SYSLOG_BUFSIZE */ -# ifndef SFS_TYPE -# define SFS_TYPE SFS_STATVFS -# endif /* ! SFS_TYPE */ - -# define USE_SIGLONGJMP 1 /* sigsetjmp needed for signal handling */ -#endif /* __svr4__ */ - -/* general System V defines */ -#ifdef SYSTEM5 -# include <sys/sysmacros.h> -# define HASUNAME 1 /* use System V uname(2) system call */ -# define SYS5SETPGRP 1 /* use System V setpgrp(2) syscall */ -# define HASSETVBUF 1 /* we have setvbuf(3) in libc */ -# ifndef HASULIMIT -# define HASULIMIT 1 /* has the ulimit(2) syscall */ -# endif /* ! HASULIMIT */ -# ifndef LA_TYPE -# ifdef MIOC_READKSYM -# define LA_TYPE LA_READKSYM /* use MIOC_READKSYM ioctl */ -# else /* MIOC_READKSYM */ -# define LA_TYPE LA_INT /* assume integer load average */ -# endif /* MIOC_READKSYM */ -# endif /* ! LA_TYPE */ -# ifndef SFS_TYPE -# define SFS_TYPE SFS_USTAT /* use System V ustat(2) syscall */ -# endif /* ! SFS_TYPE */ -# ifndef TZ_TYPE -# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */ -# endif /* ! TZ_TYPE */ -#endif /* SYSTEM5 */ - -/* general POSIX defines */ -#ifdef _POSIX_VERSION -# define HASSETSID 1 /* has Posix setsid(2) call */ -# define HASWAITPID 1 /* has Posix waitpid(2) call */ -# if _POSIX_VERSION >= 199500 && !defined(USESETEUID) -# define USESETEUID 1 /* has usable seteuid(2) call */ -# endif /* _POSIX_VERSION >= 199500 && !defined(USESETEUID) */ -#endif /* _POSIX_VERSION */ -/* -** Tweaking for systems that (for example) claim to be BSD or POSIX -** but don't have all the standard BSD or POSIX routines (boo hiss). -*/ - -#ifdef titan -# undef HASINITGROUPS /* doesn't have initgroups(3) call */ -#endif /* titan */ - -#ifdef _CRAYCOM -# undef HASSETSID /* despite POSIX claim, doesn't have setsid */ -#endif /* _CRAYCOM */ - -#ifdef MOTO -# undef USESETEUID -#endif /* MOTO */ - -/* -** Due to a "feature" in some operating systems such as Ultrix 4.3 and -** HPUX 8.0, if you receive a "No route to host" message (ICMP message -** ICMP_UNREACH_HOST) on _any_ connection, all connections to that host -** are closed. Some firewalls return this error if you try to connect -** to the IDENT port (113), so you can't receive email from these hosts -** on these systems. The firewall really should use a more specific -** message such as ICMP_UNREACH_PROTOCOL or _PORT or _FILTER_PROHIB. If -** not explicitly set to zero above, default it on. -*/ - -#ifndef IDENTPROTO -# define IDENTPROTO 1 /* use IDENT proto (RFC 1413) */ -#endif /* ! IDENTPROTO */ - -#ifndef IP_SRCROUTE -# define IP_SRCROUTE 1 /* Detect IP source routing */ -#endif /* ! IP_SRCROUTE */ - -#ifndef HASGETUSERSHELL -# define HASGETUSERSHELL 1 /* libc has getusershell(3) call */ -#endif /* ! HASGETUSERSHELL */ - -#ifndef NETUNIX -# define NETUNIX 1 /* include unix domain support */ -#endif /* ! NETUNIX */ - -#ifndef HASRANDOM -# define HASRANDOM 1 /* has random(3) support */ -#endif /* ! HASRANDOM */ - -#ifndef HASFLOCK -# define HASFLOCK 0 /* assume no flock(2) support */ -#endif /* ! HASFLOCK */ - -#ifndef HASSETREUID -# define HASSETREUID 0 /* assume no setreuid(2) call */ -#endif /* ! HASSETREUID */ - -#ifndef HASFCHMOD -# define HASFCHMOD 0 /* assume no fchmod(2) syscall */ -#endif /* ! HASFCHMOD */ - -#ifndef USESETEUID -# define USESETEUID 0 /* assume no seteuid(2) call or no saved ids */ -#endif /* ! USESETEUID */ - -#ifndef HASSETRLIMIT -# define HASSETRLIMIT 0 /* assume no setrlimit(2) support */ -#endif /* ! HASSETRLIMIT */ - -#ifndef HASULIMIT -# define HASULIMIT 0 /* assume no ulimit(2) support */ -#endif /* ! HASULIMIT */ - -#ifndef SECUREWARE -# define SECUREWARE 0 /* assume no SecureWare C2 auditing hooks */ -#endif /* ! SECUREWARE */ - -#ifndef USE_SIGLONGJMP -# define USE_SIGLONGJMP 0 /* assume setjmp handles signals properly */ -#endif /* ! USE_SIGLONGJMP */ - -#ifndef FDSET_CAST -# define FDSET_CAST /* (empty) cast for fd_set arg to select */ -#endif /* ! FDSET_CAST */ - -/* -** Pick a mailer setuid method for changing the current uid -*/ - -#define USE_SETEUID 0 -#define USE_SETREUID 1 -#define USE_SETUID 2 - -#if USESETEUID -# define MAILER_SETUID_METHOD USE_SETEUID -#else /* USESETEUID */ -# if HASSETREUID -# define MAILER_SETUID_METHOD USE_SETREUID -# else /* HASSETREUID */ -# define MAILER_SETUID_METHOD USE_SETUID -# endif /* HASSETREUID */ -#endif /* USESETEUID */ - -/* -** If no type for argument two of getgroups call is defined, assume -** it's an integer -- unfortunately, there seem to be several choices -** here. -*/ - -#ifndef GIDSET_T -# define GIDSET_T int -#endif /* ! GIDSET_T */ - -#ifndef UID_T -# define UID_T uid_t -#endif /* ! UID_T */ - -#ifndef GID_T -# define GID_T gid_t -#endif /* ! GID_T */ - -#ifndef SIZE_T -# define SIZE_T size_t -#endif /* ! SIZE_T */ - -#ifndef MODE_T -# define MODE_T mode_t -#endif /* ! MODE_T */ - -#ifndef ARGV_T -# define ARGV_T char ** -#endif /* ! ARGV_T */ - -#ifndef SOCKADDR_LEN_T -# define SOCKADDR_LEN_T int -#endif /* ! SOCKADDR_LEN_T */ - -#ifndef SOCKOPT_LEN_T -# define SOCKOPT_LEN_T int -#endif /* ! SOCKOPT_LEN_T */ - -#ifndef QUAD_T -# define QUAD_T unsigned long -#endif /* ! QUAD_T */ -/********************************************************************** -** Remaining definitions should never have to be changed. They are -** primarily to provide back compatibility for older systems -- for -** example, it includes some POSIX compatibility definitions -**********************************************************************/ - -/* System 5 compatibility */ -#ifndef S_ISREG -# define S_ISREG(foo) ((foo & S_IFMT) == S_IFREG) -#endif /* ! S_ISREG */ -#ifndef S_ISDIR -# define S_ISDIR(foo) ((foo & S_IFMT) == S_IFDIR) -#endif /* ! S_ISDIR */ -#if !defined(S_ISLNK) && defined(S_IFLNK) -# define S_ISLNK(foo) ((foo & S_IFMT) == S_IFLNK) -#endif /* !defined(S_ISLNK) && defined(S_IFLNK) */ -#if !defined(S_ISFIFO) -# if defined(S_IFIFO) -# define S_ISFIFO(foo) ((foo & S_IFMT) == S_IFIFO) -# else /* defined(S_IFIFO) */ -# define S_ISFIFO(foo) FALSE -# endif /* defined(S_IFIFO) */ -#endif /* !defined(S_ISFIFO) */ -#ifndef S_IRUSR -# define S_IRUSR 0400 -#endif /* ! S_IRUSR */ -#ifndef S_IWUSR -# define S_IWUSR 0200 -#endif /* ! S_IWUSR */ -#ifndef S_IRGRP -# define S_IRGRP 0040 -#endif /* ! S_IRGRP */ -#ifndef S_IWGRP -# define S_IWGRP 0020 -#endif /* ! S_IWGRP */ -#ifndef S_IROTH -# define S_IROTH 0004 -#endif /* ! S_IROTH */ -#ifndef S_IWOTH -# define S_IWOTH 0002 -#endif /* ! S_IWOTH */ - -#ifndef O_ACCMODE -# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) -#endif /* ! O_ACCMODE */ - -/* close-on-exec flag */ -#ifndef FD_CLOEXEC -# define FD_CLOEXEC 1 -#endif /* ! FD_CLOEXEC */ - -/* -** Older systems don't have this error code -- it should be in -** /usr/include/sysexits.h. -*/ - -#ifndef EX_CONFIG -# define EX_CONFIG 78 /* configuration error */ -#endif /* ! EX_CONFIG */ - -/* pseudo-codes */ -#define EX_QUIT 22 /* drop out of server immediately */ -#define EX_RESTART 23 /* restart sendmail daemon */ -#define EX_SHUTDOWN 24 /* shutdown sendmail daemon */ - -/* pseudo-code used for mci_setstat */ -#define EX_NOTSTICKY -5 /* don't save persistent status */ - - -/* -** An "impossible" file mode to indicate that the file does not exist. -*/ - -#define ST_MODE_NOFILE 0171147 /* unlikely to occur */ - - -/* type of arbitrary pointer */ -#ifndef ARBPTR_T -# define ARBPTR_T void * -#endif /* ! ARBPTR_T */ - -#ifndef __P -# include "sendmail/cdefs.h" -#endif /* ! __P */ - -#if HESIOD && !defined(NAMED_BIND) -# define NAMED_BIND 1 /* not one without the other */ -#endif /* HESIOD && !defined(NAMED_BIND) */ - -# if NAMED_BIND && !defined( __ksr__ ) && !defined( h_errno ) -extern int h_errno; -# endif /* NAMED_BIND && !defined( __ksr__ ) && !defined( h_errno ) */ - -#ifdef LDAPMAP -# include <sys/time.h> -# include <lber.h> -# include <ldap.h> - -/* Some LDAP constants */ -# define LDAPMAP_FALSE 0 -# define LDAPMAP_TRUE 1 - -/* -** ldap_init(3) is broken in Umich 3.x and OpenLDAP 1.0/1.1. -** Use the lack of LDAP_OPT_SIZELIMIT to detect old API implementations -** and assume (falsely) that all old API implementations are broken. -** (OpenLDAP 1.2 and later have a working ldap_init(), add -DUSE_LDAP_INIT) -*/ - -# if defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_INIT) -# define USE_LDAP_INIT 1 -# endif /* defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_INIT) */ - -/* -** LDAP_OPT_SIZELIMIT is not defined under Umich 3.x nor OpenLDAP 1.x, -** hence ldap_set_option() must not exist. -*/ - -# if defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_SET_OPTION) -# define USE_LDAP_SET_OPTION 1 -# endif /* defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_SET_OPTION) */ - -#endif /* LDAPMAP */ - -/* -** Do some required dependencies -*/ - -#if NETINET || NETINET6 || NETISO -# ifndef SMTP -# define SMTP 1 /* enable user and server SMTP */ -# endif /* ! SMTP */ -# ifndef QUEUE -# define QUEUE 1 /* enable queueing */ -# endif /* ! QUEUE */ -# ifndef DAEMON -# define DAEMON 1 /* include the daemon (requires IPC & SMTP) */ -# endif /* ! DAEMON */ -#endif /* NETINET || NETINET6 || NETISO */ - - -/* -** Arrange to use either varargs or stdargs -*/ - -#ifdef __STDC__ - -# include <stdarg.h> - -# define VA_LOCAL_DECL va_list ap; -# define VA_START(f) va_start(ap, f) -# define VA_END va_end(ap) - -#else /* __STDC__ */ - -# include <varargs.h> - -# define VA_LOCAL_DECL va_list ap; -# define VA_START(f) va_start(ap) -# define VA_END va_end(ap) - -#endif /* __STDC__ */ - -#if HASUNAME -# include <sys/utsname.h> -# ifdef newstr -# undef newstr -# endif /* newstr */ -#else /* HASUNAME */ -# define NODE_LENGTH 32 -struct utsname -{ - char nodename[NODE_LENGTH + 1]; -}; -#endif /* HASUNAME */ - -#if !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_) && !defined(NonStop_UX_BXX) && !defined(ALTOS_SYSTEM_V) -# define MAXHOSTNAMELEN 256 -#endif /* !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_) && !defined(NonStop_UX_BXX) && !defined(ALTOS_SYSTEM_V) */ - -#if !defined(SIGCHLD) && defined(SIGCLD) -# define SIGCHLD SIGCLD -#endif /* !defined(SIGCHLD) && defined(SIGCLD) */ - -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -#endif /* ! STDIN_FILENO */ - -#ifndef STDOUT_FILENO -# define STDOUT_FILENO 1 -#endif /* ! STDOUT_FILENO */ - -#ifndef STDERR_FILENO -# define STDERR_FILENO 2 -#endif /* ! STDERR_FILENO */ - -#ifndef LOCK_SH -# define LOCK_SH 0x01 /* shared lock */ -# define LOCK_EX 0x02 /* exclusive lock */ -# define LOCK_NB 0x04 /* non-blocking lock */ -# define LOCK_UN 0x08 /* unlock */ -#endif /* ! LOCK_SH */ - -#ifndef S_IXOTH -# define S_IXOTH (S_IEXEC >> 6) -#endif /* ! S_IXOTH */ - -#ifndef S_IXGRP -# define S_IXGRP (S_IEXEC >> 3) -#endif /* ! S_IXGRP */ - -#ifndef S_IXUSR -# define S_IXUSR (S_IEXEC) -#endif /* ! S_IXUSR */ - -#ifndef SEEK_SET -# define SEEK_SET 0 -# define SEEK_CUR 1 -# define SEEK_END 2 -#endif /* ! SEEK_SET */ - -#ifndef SIG_ERR -# define SIG_ERR ((void (*)()) -1) -#endif /* ! SIG_ERR */ - -#ifndef WEXITSTATUS -# define WEXITSTATUS(st) (((st) >> 8) & 0377) -#endif /* ! WEXITSTATUS */ -#ifndef WIFEXITED -# define WIFEXITED(st) (((st) & 0377) == 0) -#endif /* ! WIFEXITED */ -#ifndef WIFSTOPPED -# define WIFSTOPPED(st) (((st) & 0100) == 0) -#endif /* ! WIFSTOPPED */ -#ifndef WCOREDUMP -# define WCOREDUMP(st) (((st) & 0200) != 0) -#endif /* ! WCOREDUMP */ -#ifndef WTERMSIG -# define WTERMSIG(st) (((st) & 0177)) -#endif /* ! WTERMSIG */ - -#ifndef SIGFUNC_DEFINED -typedef void (*sigfunc_t) __P((int)); -#endif /* ! SIGFUNC_DEFINED */ -#ifndef SIGFUNC_RETURN -# define SIGFUNC_RETURN -#endif /* ! SIGFUNC_RETURN */ -#ifndef SIGFUNC_DECL -# define SIGFUNC_DECL void -#endif /* ! SIGFUNC_DECL */ - -/* size of syslog buffer */ -#ifndef SYSLOG_BUFSIZE -# define SYSLOG_BUFSIZE 1024 -#endif /* ! SYSLOG_BUFSIZE */ - -/* -** Size of prescan buffer. -** Despite comments in the _sendmail_ book, this probably should -** not be changed; there are some hard-to-define dependencies. -*/ - -#define PSBUFSIZE (MAXNAME + MAXATOM) /* size of prescan buffer */ - -/* fork routine -- set above using #ifdef _osname_ or in Makefile */ -#ifndef FORK -# define FORK fork /* function to call to fork mailer */ -#endif /* ! FORK */ - -/* setting h_errno */ -#ifndef SM_SET_H_ERRNO -# define SM_SET_H_ERRNO(err) h_errno = (err) -#endif /* SM_SET_H_ERRNO */ - -/* random routine -- set above using #ifdef _osname_ or in Makefile */ -#if HASRANDOM -# define get_random() random() -#else /* HASRANDOM */ -# define get_random() ((long) rand()) -# ifndef RANDOMSHIFT -# define RANDOMSHIFT 8 -# endif /* RANDOMSHIFT */ -#endif /* HASRANDOM */ - -/* -** Default to using scanf in readcf. -*/ - -#ifndef SCANF -# define SCANF 1 -#endif /* ! SCANF */ - -#if _FFR_MILTER -/* 32 bit type */ -# ifndef SM_INT32 -# define SM_INT32 int32_t -# endif /* SM_INT32 */ -#endif /* _FFR_MILTER */ - -/* -** SVr4 and similar systems use different routines for setjmp/longjmp -** with signal support -*/ - -#if USE_SIGLONGJMP -# ifdef jmp_buf -# undef jmp_buf -# endif /* jmp_buf */ -# define jmp_buf sigjmp_buf -# ifdef setjmp -# undef setjmp -# endif /* setjmp */ -# define setjmp(env) sigsetjmp(env, 1) -# ifdef longjmp -# undef longjmp -# endif /* longjmp */ -# define longjmp(env, val) siglongjmp(env, val) -#endif /* USE_SIGLONGJMP */ - -#if !defined(NGROUPS_MAX) && defined(NGROUPS) -# define NGROUPS_MAX NGROUPS /* POSIX naming convention */ -#endif /* !defined(NGROUPS_MAX) && defined(NGROUPS) */ - -/* -** Some snprintf() implementations are rumored not to NUL terminate. -*/ -#if SNPRINTF_IS_BROKEN -# ifdef snprintf -# undef snprintf -# endif /* snprintf */ -# define snprintf sm_snprintf -# ifdef vsnprintf -# undef vsnprintf -# endif /* vsnprintf */ -# define vsnprintf sm_vsnprintf -#endif /* SNPRINTF_IS_BROKEN */ - -/* -** If we don't have a system syslog, simulate it. -*/ - -#if !LOG -# define LOG_EMERG 0 /* system is unusable */ -# define LOG_ALERT 1 /* action must be taken immediately */ -# define LOG_CRIT 2 /* critical conditions */ -# define LOG_ERR 3 /* error conditions */ -# define LOG_WARNING 4 /* warning conditions */ -# define LOG_NOTICE 5 /* normal but significant condition */ -# define LOG_INFO 6 /* informational */ -# define LOG_DEBUG 7 /* debug-level messages */ -#endif /* !LOG */ - -#if SFIO -# ifdef ERRLIST_PREDEFINED -# undef ERRLIST_PREDEFINED -# endif /* ERRLIST_PREDEFINED */ -# if !HASSNPRINTF -# define HASSNPRINTF 1 /* sfio includes snprintf() */ -# endif /* !HASSNPRINTF */ -#endif /* SFIO */ -#ifndef SFIO_STDIO_COMPAT -# define SFIO_STDIO_COMPAT 0 -#endif /* ! SFIO_STDIO_COMPAT */ +#include <sm/conf.h> -#endif /* CONF_H */ +#endif /* ! CONF_H */ diff --git a/contrib/sendmail/src/err.c b/contrib/sendmail/src/err.c index 6e02d44..3a75dd5 100644 --- a/contrib/sendmail/src/err.c +++ b/contrib/sendmail/src/err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -11,44 +11,99 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: err.c,v 8.120.4.5 2001/08/17 22:09:40 ca Exp $"; -#endif /* ! lint */ +#include <sendmail.h> + +SM_RCSID("@(#)$Id: err.c,v 8.189 2002/01/09 18:52:30 ca Exp $") /* $FreeBSD$ */ -#include <sendmail.h> -#ifdef LDAPMAP +#if LDAPMAP # include <lber.h> # include <ldap.h> /* for LDAP error codes */ #endif /* LDAPMAP */ - static void putoutmsg __P((char *, bool, bool)); static void puterrmsg __P((char *)); static char *fmtmsg __P((char *, const char *, const char *, const char *, int, const char *, va_list)); /* +** FATAL_ERROR -- handle a fatal exception +** +** This function is installed as the default exception handler +** in the main sendmail process, and in all child processes +** that we create. Its job is to handle exceptions that are not +** handled at a lower level. +** +** The theory is that unhandled exceptions will be 'fatal' class +** exceptions (with an "F:" prefix), such as the out-of-memory +** exception "F:sm.heap". As such, they are handled by exiting +** the process in exactly the same way that xalloc() in Sendmail 8.10 +** exits the process when it fails due to lack of memory: +** we call syserr with a message beginning with "!". +** +** Parameters: +** exc -- exception which is terminating this process +** +** Returns: +** none +*/ + +void +fatal_error(exc) + SM_EXC_T *exc; +{ + static char buf[256]; + SM_FILE_T f; + + /* + ** This function may be called when the heap is exhausted. + ** The following code writes the message for 'exc' into our + ** static buffer without allocating memory or raising exceptions. + */ + + sm_strio_init(&f, buf, sizeof(buf)); + sm_exc_write(exc, &f); + (void) sm_io_flush(&f, SM_TIME_DEFAULT); + + /* + ** Terminate the process after logging an error and cleaning up. + ** Problems: + ** - syserr decides what class of error this is by looking at errno. + ** That's no good; we should look at the exc structure. + ** - The cleanup code should be moved out of syserr + ** and into individual exception handlers + ** that are part of the module they clean up after. + */ + + errno = ENOMEM; + syserr("!%s", buf); +} + +/* ** SYSERR -- Print error message. ** -** Prints an error message via printf to the diagnostic output. +** Prints an error message via sm_io_printf to the diagnostic output. ** ** If the first character of the syserr message is `!' it will ** log this as an ALERT message and exit immediately. This can ** leave queue files in an indeterminate state, so it should not ** be used lightly. ** +** If the first character of the syserr message is '!' or '@' +** then syserr knows that the process is about to be terminated, +** so the SMTP reply code defaults to 421. Otherwise, the +** reply code defaults to 451 or 554, depending on errno. +** ** Parameters: -** fmt -- the format string. If it does not begin with -** a three-digit SMTP reply code, either 554 or -** 451 is assumed depending on whether errno -** is set. +** fmt -- the format string. An optional '!' or '@', +** followed by an optional three-digit SMTP +** reply code, followed by message text. ** (others) -- parameters ** ** Returns: ** none -** Through TopFrame if QuickAbort is set. +** Raises E:mta.quickabort if QuickAbort is set. ** ** Side Effects: ** increments Errors. @@ -75,22 +130,45 @@ syserr(fmt, va_alist) register char *p; int save_errno = errno; bool panic; + bool exiting; char *user; char *enhsc; char *errtxt; struct passwd *pw; char ubuf[80]; - VA_LOCAL_DECL + SM_VA_LOCAL_DECL - panic = *fmt == '!'; - if (panic) + switch (*fmt) { - fmt++; - HoldErrs = FALSE; + case '!': + ++fmt; + panic = true; + exiting = true; + break; + case '@': + ++fmt; + panic = false; + exiting = true; + break; + default: + panic = false; + exiting = false; + break; } /* format and output the error message */ - if (save_errno == 0) + if (exiting) + { + /* + ** Since we are terminating the process, + ** we are aborting the entire SMTP session, + ** rather than just the current transaction. + */ + + p = "421"; + enhsc = "4.0.0"; + } + else if (save_errno == 0) { p = "554"; enhsc = "5.0.0"; @@ -100,17 +178,19 @@ syserr(fmt, va_alist) p = "451"; enhsc = "4.0.0"; } - VA_START(fmt); + SM_VA_START(ap, fmt); errtxt = fmtmsg(MsgBuf, (char *) NULL, p, enhsc, save_errno, fmt, ap); - VA_END; + SM_VA_END(ap); puterrmsg(MsgBuf); /* save this message for mailq printing */ if (!panic && CurEnv != NULL) { - if (CurEnv->e_message != NULL) + char *nmsg = sm_rpool_strdup_x(CurEnv->e_rpool, errtxt); + + if (CurEnv->e_rpool == NULL && CurEnv->e_message != NULL) sm_free(CurEnv->e_message); - CurEnv->e_message = newstr(errtxt); + CurEnv->e_message = nmsg; } /* determine exit status if not already set */ @@ -121,7 +201,7 @@ syserr(fmt, va_alist) else ExitStat = EX_OSERR; if (tTd(54, 1)) - dprintf("syserr: ExitStat = %d\n", ExitStat); + sm_dprintf("syserr: ExitStat = %d\n", ExitStat); } pw = sm_getpwuid(RealUid); @@ -130,7 +210,7 @@ syserr(fmt, va_alist) else { user = ubuf; - snprintf(ubuf, sizeof ubuf, "UID%d", (int) RealUid); + (void) sm_snprintf(ubuf, sizeof ubuf, "UID%d", (int) RealUid); } if (LogLevel > 0) @@ -159,13 +239,13 @@ syserr(fmt, va_alist) #ifdef ESTALE case ESTALE: #endif /* ESTALE */ - printopenfds(TRUE); - mci_dump_all(TRUE); + printopenfds(true); + mci_dump_all(true); break; } if (panic) { -#ifdef XLA +#if XLA xla_all_end(); #endif /* XLA */ sync_queue_time(); @@ -175,21 +255,21 @@ syserr(fmt, va_alist) } errno = 0; if (QuickAbort) - longjmp(TopFrame, 2); + sm_exc_raisenew_x(&EtypeQuickAbort, 2); } -/* +/* ** USRERR -- Signal user error. ** ** This is much like syserr except it is for user errors. ** ** Parameters: ** fmt -- the format string. If it does not begin with -** a three-digit SMTP reply code, 501 is assumed. -** (others) -- printf strings +** a three-digit SMTP reply code, 550 is assumed. +** (others) -- sm_io_printf strings ** ** Returns: ** none -** Through TopFrame if QuickAbort is set. +** Raises E:mta.quickabort if QuickAbort is set. ** ** Side Effects: ** increments Errors. @@ -207,7 +287,7 @@ usrerr(fmt, va_alist) { char *enhsc; char *errtxt; - VA_LOCAL_DECL + SM_VA_LOCAL_DECL if (fmt[0] == '5' || fmt[0] == '6') enhsc = "5.0.0"; @@ -217,9 +297,9 @@ usrerr(fmt, va_alist) enhsc = "2.0.0"; else enhsc = NULL; - VA_START(fmt); - errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "501", enhsc, 0, fmt, ap); - VA_END; + SM_VA_START(ap, fmt); + errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "550", enhsc, 0, fmt, ap); + SM_VA_END(ap); if (SuprErrs) return; @@ -236,32 +316,33 @@ usrerr(fmt, va_alist) case '5': case '6': - if (CurEnv->e_message != NULL) + if (CurEnv->e_rpool == NULL && CurEnv->e_message != NULL) sm_free(CurEnv->e_message); if (MsgBuf[0] == '6') { char buf[MAXLINE]; - snprintf(buf, sizeof buf, "Postmaster warning: %.*s", - (int) sizeof buf - 22, errtxt); - CurEnv->e_message = newstr(buf); + (void) sm_snprintf(buf, sizeof buf, + "Postmaster warning: %.*s", + (int) sizeof buf - 22, errtxt); + CurEnv->e_message = + sm_rpool_strdup_x(CurEnv->e_rpool, buf); } else { - CurEnv->e_message = newstr(errtxt); + CurEnv->e_message = + sm_rpool_strdup_x(CurEnv->e_rpool, errtxt); } break; } puterrmsg(MsgBuf); - if (LogLevel > 3 && LogUsrErrs) sm_syslog(LOG_NOTICE, CurEnv->e_id, "%.900s", errtxt); - if (QuickAbort) - longjmp(TopFrame, 1); + sm_exc_raisenew_x(&EtypeQuickAbort, 1); } -/* +/* ** USRERRENH -- Signal user error. ** ** Same as usrerr but with enhanced status code. @@ -269,12 +350,12 @@ usrerr(fmt, va_alist) ** Parameters: ** enhsc -- the enhanced status code. ** fmt -- the format string. If it does not begin with -** a three-digit SMTP reply code, 501 is assumed. -** (others) -- printf strings +** a three-digit SMTP reply code, 550 is assumed. +** (others) -- sm_io_printf strings ** ** Returns: ** none -** Through TopFrame if QuickAbort is set. +** Raises E:mta.quickabort if QuickAbort is set. ** ** Side Effects: ** increments Errors. @@ -292,7 +373,7 @@ usrerrenh(enhsc, fmt, va_alist) #endif /* __STDC__ */ { char *errtxt; - VA_LOCAL_DECL + SM_VA_LOCAL_DECL if (enhsc == NULL || *enhsc == '\0') { @@ -303,9 +384,9 @@ usrerrenh(enhsc, fmt, va_alist) else if (fmt[0] == '2') enhsc = "2.0.0"; } - VA_START(fmt); - errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "501", enhsc, 0, fmt, ap); - VA_END; + SM_VA_START(ap, fmt); + errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "550", enhsc, 0, fmt, ap); + SM_VA_END(ap); if (SuprErrs) return; @@ -322,38 +403,39 @@ usrerrenh(enhsc, fmt, va_alist) case '5': case '6': - if (CurEnv->e_message != NULL) + if (CurEnv->e_rpool == NULL && CurEnv->e_message != NULL) sm_free(CurEnv->e_message); if (MsgBuf[0] == '6') { char buf[MAXLINE]; - snprintf(buf, sizeof buf, "Postmaster warning: %.*s", - (int) sizeof buf - 22, errtxt); - CurEnv->e_message = newstr(buf); + (void) sm_snprintf(buf, sizeof buf, + "Postmaster warning: %.*s", + (int) sizeof buf - 22, errtxt); + CurEnv->e_message = + sm_rpool_strdup_x(CurEnv->e_rpool, buf); } else { - CurEnv->e_message = newstr(errtxt); + CurEnv->e_message = + sm_rpool_strdup_x(CurEnv->e_rpool, errtxt); } break; } puterrmsg(MsgBuf); - if (LogLevel > 3 && LogUsrErrs) sm_syslog(LOG_NOTICE, CurEnv->e_id, "%.900s", errtxt); - if (QuickAbort) - longjmp(TopFrame, 1); + sm_exc_raisenew_x(&EtypeQuickAbort, 1); } -/* +/* ** MESSAGE -- print message (not necessarily an error) ** ** Parameters: -** msg -- the message (printf fmt) -- it can begin with +** msg -- the message (sm_io_printf fmt) -- it can begin with ** an SMTP reply code. If not, 050 is assumed. -** (others) -- printf arguments +** (others) -- sm_io_printf arguments ** ** Returns: ** none @@ -373,13 +455,13 @@ message(msg, va_alist) #endif /* __STDC__ */ { char *errtxt; - VA_LOCAL_DECL + SM_VA_LOCAL_DECL errno = 0; - VA_START(msg); + SM_VA_START(ap, msg); errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "050", (char *) NULL, 0, msg, ap); - VA_END; - putoutmsg(MsgBuf, FALSE, FALSE); + SM_VA_END(ap); + putoutmsg(MsgBuf, false, false); /* save this message for mailq printing */ switch (MsgBuf[0]) @@ -391,22 +473,23 @@ message(msg, va_alist) /* FALLTHROUGH */ case '5': - if (CurEnv->e_message != NULL) + if (CurEnv->e_rpool == NULL && CurEnv->e_message != NULL) sm_free(CurEnv->e_message); - CurEnv->e_message = newstr(errtxt); + CurEnv->e_message = + sm_rpool_strdup_x(CurEnv->e_rpool, errtxt); break; } } -/* +/* ** NMESSAGE -- print message (not necessarily an error) ** ** Just like "message" except it never puts the to... tag on. ** ** Parameters: -** msg -- the message (printf fmt) -- if it begins +** msg -- the message (sm_io_printf fmt) -- if it begins ** with a three digit SMTP reply code, that is used, ** otherwise 050 is assumed. -** (others) -- printf arguments +** (others) -- sm_io_printf arguments ** ** Returns: ** none @@ -426,14 +509,14 @@ nmessage(msg, va_alist) #endif /* __STDC__ */ { char *errtxt; - VA_LOCAL_DECL + SM_VA_LOCAL_DECL errno = 0; - VA_START(msg); + SM_VA_START(ap, msg); errtxt = fmtmsg(MsgBuf, (char *) NULL, "050", (char *) NULL, 0, msg, ap); - VA_END; - putoutmsg(MsgBuf, FALSE, FALSE); + SM_VA_END(ap); + putoutmsg(MsgBuf, false, false); /* save this message for mailq printing */ switch (MsgBuf[0]) @@ -445,20 +528,21 @@ nmessage(msg, va_alist) /* FALLTHROUGH */ case '5': - if (CurEnv->e_message != NULL) + if (CurEnv->e_rpool == NULL && CurEnv->e_message != NULL) sm_free(CurEnv->e_message); - CurEnv->e_message = newstr(errtxt); + CurEnv->e_message = + sm_rpool_strdup_x(CurEnv->e_rpool, errtxt); break; } } -/* +/* ** PUTOUTMSG -- output error message to transcript and channel ** ** Parameters: ** msg -- message to output (in SMTP format). -** holdmsg -- if TRUE, don't output a copy of the message to +** holdmsg -- if true, don't output a copy of the message to ** our output channel. -** heldmsg -- if TRUE, this is a previously held message; +** heldmsg -- if true, this is a previously held message; ** don't log it to the transcript file. ** ** Returns: @@ -481,7 +565,7 @@ putoutmsg(msg, holdmsg, heldmsg) /* display for debugging */ if (tTd(54, 8)) - dprintf("--- %s%s%s\n", msg, holdmsg ? " (hold)" : "", + sm_dprintf("--- %s%s%s\n", msg, holdmsg ? " (hold)" : "", heldmsg ? " (held)" : ""); /* map warnings to something SMTP can handle */ @@ -493,12 +577,13 @@ putoutmsg(msg, holdmsg, heldmsg) /* output to transcript if serious */ if (!heldmsg && CurEnv != NULL && CurEnv->e_xfp != NULL && strchr("45", msg[0]) != NULL) - fprintf(CurEnv->e_xfp, "%s\n", msg); + (void) sm_io_fprintf(CurEnv->e_xfp, SM_TIME_DEFAULT, "%s\n", + msg); - if (LogLevel >= 15 && (OpMode == MD_SMTP || OpMode == MD_DAEMON)) + if (LogLevel > 14 && (OpMode == MD_SMTP || OpMode == MD_DAEMON)) sm_syslog(LOG_INFO, CurEnv->e_id, - "--> %s%s", - msg, holdmsg ? " (held)" : ""); + "--- %s%s%s", msg, holdmsg ? " (hold)" : "", + heldmsg ? " (held)" : ""); if (msgcode == '8') msg[0] = '0'; @@ -512,11 +597,11 @@ putoutmsg(msg, holdmsg, heldmsg) msg[0] = msgcode; if (HeldMessageBuf[0] == '5' && msgcode == '4') return; - snprintf(HeldMessageBuf, sizeof HeldMessageBuf, "%s", msg); + (void) sm_strlcpy(HeldMessageBuf, msg, sizeof HeldMessageBuf); return; } - (void) fflush(stdout); + (void) sm_io_flush(smioout, SM_TIME_DEFAULT); if (OutChannel == NULL) return; @@ -537,15 +622,21 @@ putoutmsg(msg, holdmsg, heldmsg) /* if DisConnected, OutChannel now points to the transcript */ if (!DisConnected && (OpMode == MD_SMTP || OpMode == MD_DAEMON || OpMode == MD_ARPAFTP)) - fprintf(OutChannel, "%s\r\n", msg); + (void) sm_io_fprintf(OutChannel, SM_TIME_DEFAULT, "%s\r\n", + msg); else - fprintf(OutChannel, "%s\n", errtxt); + (void) sm_io_fprintf(OutChannel, SM_TIME_DEFAULT, "%s\n", + errtxt); if (TrafficLogFile != NULL) - fprintf(TrafficLogFile, "%05d >>> %s\n", (int) getpid(), - (OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : errtxt); + (void) sm_io_fprintf(TrafficLogFile, SM_TIME_DEFAULT, + "%05d >>> %s\n", (int) CurrentPid, + (OpMode == MD_SMTP || OpMode == MD_DAEMON) + ? msg : errtxt); +#if !PIPELINING + /* XXX can't flush here for SMTP pipelining */ if (msg[3] == ' ') - (void) fflush(OutChannel); - if (!ferror(OutChannel) || DisConnected) + (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT); + if (!sm_io_error(OutChannel) || DisConnected) return; /* @@ -554,19 +645,20 @@ putoutmsg(msg, holdmsg, heldmsg) ** rude servers don't read result. */ - if (InChannel == NULL || feof(InChannel) || ferror(InChannel) || - strncmp(msg, "221", 3) == 0) + if (InChannel == NULL || sm_io_eof(InChannel) || + sm_io_error(InChannel) || strncmp(msg, "221", 3) == 0) return; /* can't call syserr, 'cause we are using MsgBuf */ - HoldErrs = TRUE; + HoldErrs = true; if (LogLevel > 0) sm_syslog(LOG_CRIT, CurEnv->e_id, "SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s", - CurHostName == NULL ? "NO-HOST" : CurHostName, - shortenstring(msg, MAXSHORTSTR), errstring(errno)); + CURHOSTNAME, + shortenstring(msg, MAXSHORTSTR), sm_errstring(errno)); +#endif /* !PIPELINING */ } -/* +/* ** PUTERRMSG -- like putoutmsg, but does special processing for error messages ** ** Parameters: @@ -586,11 +678,11 @@ puterrmsg(msg) char msgcode = msg[0]; /* output the message as usual */ - putoutmsg(msg, HoldErrs, FALSE); + putoutmsg(msg, HoldErrs, false); /* be careful about multiple error messages */ if (OnlyOneError) - HoldErrs = TRUE; + HoldErrs = true; /* signal the error */ Errors++; @@ -609,7 +701,7 @@ puterrmsg(msg) CurEnv->e_flags |= EF_FATALERRS; } } -/* +/* ** ISENHSC -- check whether a string contains an enhanced status code ** ** Parameters: @@ -648,7 +740,7 @@ isenhsc(s, delim) return 0; return l + h; } -/* +/* ** EXTENHSC -- check and extract an enhanced status code ** ** Parameters: @@ -665,6 +757,7 @@ isenhsc(s, delim) ** Side Effects: ** fills e with enhanced status code. */ + int extenhsc(s, delim, e) const char *s; @@ -701,7 +794,7 @@ extenhsc(s, delim, e) e[l + h] = '\0'; return l + h; } -/* +/* ** FMTMSG -- format a message into buffer. ** ** Parameters: @@ -728,7 +821,7 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap) const char *enhsc; int eno; const char *fmt; - va_list ap; + SM_VA_LOCAL_DECL { char del; int l; @@ -745,7 +838,15 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap) del = '-'; else del = ' '; - (void) snprintf(eb, spaceleft, "%3.3s%c", num, del); +#if _FFR_SOFT_BOUNCE + if (SoftBounce && num[0] == '5') + { + /* replace 5 by 4 */ + (void) sm_snprintf(eb, spaceleft, "4%2.2s%c", num + 1, del); + } + else +#endif /* _FFR_SOFT_BOUNCE */ + (void) sm_snprintf(eb, spaceleft, "%3.3s%c", num, del); eb += 4; spaceleft -= 4; @@ -753,7 +854,7 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap) { /* copy enh.status code including trailing blank */ l++; - (void) strlcpy(eb, fmt, l + 1); + (void) sm_strlcpy(eb, fmt, l + 1); eb += l; spaceleft -= l; fmt += l; @@ -761,19 +862,26 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap) else if ((l = isenhsc(enhsc, '\0')) > 0 && l < spaceleft - 4) { /* copy enh.status code */ - (void) strlcpy(eb, enhsc, l + 1); + (void) sm_strlcpy(eb, enhsc, l + 1); eb[l] = ' '; eb[++l] = '\0'; eb += l; spaceleft -= l; } +#if _FFR_SOFT_BOUNCE + if (SoftBounce && eb[-l] == '5') + { + /* replace 5 by 4 */ + eb[-l] = '4'; + } +#endif /* _FFR_SOFT_BOUNCE */ errtxt = eb; /* output the file name and line number */ if (FileName != NULL) { - (void) snprintf(eb, spaceleft, "%s: line %d: ", - shortenstring(FileName, 83), LineNumber); + (void) sm_snprintf(eb, spaceleft, "%s: line %d: ", + shortenstring(FileName, 83), LineNumber); eb += (l = strlen(eb)); spaceleft -= l; } @@ -800,26 +908,26 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap) strncmp(num, "550", 3) == 0 || strncmp(num, "553", 3) == 0)) { - (void) snprintf(eb, spaceleft, "%s... ", - shortenstring(to, MAXSHORTSTR)); + (void) sm_strlcpyn(eb, spaceleft, 2, + shortenstring(to, MAXSHORTSTR), "... "); spaceleft -= strlen(eb); while (*eb != '\0') *eb++ &= 0177; } /* output the message */ - (void) vsnprintf(eb, spaceleft, fmt, ap); + (void) sm_vsnprintf(eb, spaceleft, fmt, ap); spaceleft -= strlen(eb); while (*eb != '\0') *eb++ &= 0177; /* output the error code, if any */ if (eno != 0) - (void) snprintf(eb, spaceleft, ": %s", errstring(eno)); + (void) sm_strlcpyn(eb, spaceleft, 2, ": ", sm_errstring(eno)); return errtxt; } -/* +/* ** BUFFER_ERRORS -- arrange to buffer future error messages ** ** Parameters: @@ -833,9 +941,9 @@ void buffer_errors() { HeldMessageBuf[0] = '\0'; - HoldErrs = TRUE; + HoldErrs = true; } -/* +/* ** FLUSH_ERRORS -- flush the held error message buffer ** ** Parameters: @@ -851,12 +959,12 @@ flush_errors(print) bool print; { if (print && HeldMessageBuf[0] != '\0') - putoutmsg(HeldMessageBuf, FALSE, TRUE); + putoutmsg(HeldMessageBuf, false, true); HeldMessageBuf[0] = '\0'; - HoldErrs = FALSE; + HoldErrs = false; } -/* -** ERRSTRING -- return string description of error code +/* +** SM_ERRSTRING -- return string description of error code ** ** Parameters: ** errnum -- the error number to translate @@ -869,12 +977,16 @@ flush_errors(print) */ const char * -errstring(errnum) +sm_errstring(errnum) int errnum; { char *dnsmsg; char *bp; static char buf[MAXLINE]; +#if HASSTRERROR + char *err; + char errbuf[30]; +#endif /* HASSTRERROR */ #if !HASSTRERROR && !defined(ERRLIST_PREDEFINED) extern char *sys_errlist[]; extern int sys_nerr; @@ -889,58 +1001,67 @@ errstring(errnum) dnsmsg = NULL; switch (errnum) { -#if defined(DAEMON) && defined(ETIMEDOUT) case ETIMEDOUT: case ECONNRESET: bp = buf; -# if HASSTRERROR - snprintf(bp, SPACELEFT(buf, bp), "%s", strerror(errnum)); -# else /* HASSTRERROR */ +#if HASSTRERROR + err = strerror(errnum); + if (err == NULL) + { + (void) sm_snprintf(errbuf, sizeof errbuf, + "Error %d", errnum); + err = errbuf; + } + (void) sm_strlcpy(bp, err, SPACELEFT(buf, bp)); +#else /* HASSTRERROR */ if (errnum >= 0 && errnum < sys_nerr) - snprintf(bp, SPACELEFT(buf, bp), "%s", sys_errlist[errnum]); + (void) sm_strlcpy(bp, sys_errlist[errnum], + SPACELEFT(buf, bp)); else - snprintf(bp, SPACELEFT(buf, bp), "Error %d", errnum); -# endif /* HASSTRERROR */ + (void) sm_snprintf(bp, SPACELEFT(buf, bp), + "Error %d", errnum); +#endif /* HASSTRERROR */ bp += strlen(bp); if (CurHostName != NULL) { if (errnum == ETIMEDOUT) { - snprintf(bp, SPACELEFT(buf, bp), " with "); + (void) sm_snprintf(bp, SPACELEFT(buf, bp), + " with "); bp += strlen(bp); } else { bp = buf; - snprintf(bp, SPACELEFT(buf, bp), + (void) sm_snprintf(bp, SPACELEFT(buf, bp), "Connection reset by "); bp += strlen(bp); } - snprintf(bp, SPACELEFT(buf, bp), "%s", - shortenstring(CurHostName, MAXSHORTSTR)); + (void) sm_strlcpy(bp, + shortenstring(CurHostName, MAXSHORTSTR), + SPACELEFT(buf, bp)); bp += strlen(buf); } if (SmtpPhase != NULL) { - snprintf(bp, SPACELEFT(buf, bp), " during %s", - SmtpPhase); + (void) sm_snprintf(bp, SPACELEFT(buf, bp), + " during %s", SmtpPhase); } return buf; case EHOSTDOWN: if (CurHostName == NULL) break; - (void) snprintf(buf, sizeof buf, "Host %s is down", + (void) sm_snprintf(buf, sizeof buf, "Host %s is down", shortenstring(CurHostName, MAXSHORTSTR)); return buf; case ECONNREFUSED: if (CurHostName == NULL) break; - (void) snprintf(buf, sizeof buf, "Connection refused by %s", + (void) sm_strlcpyn(buf, sizeof buf, 2, "Connection refused by ", shortenstring(CurHostName, MAXSHORTSTR)); return buf; -#endif /* defined(DAEMON) && defined(ETIMEDOUT) */ #if NAMED_BIND case HOST_NOT_FOUND + E_DNSBASE: @@ -1008,29 +1129,35 @@ errstring(errnum) if (dnsmsg != NULL) { bp = buf; - bp += strlcpy(bp, "Name server: ", sizeof buf); + bp += sm_strlcpy(bp, "Name server: ", sizeof buf); if (CurHostName != NULL) { - snprintf(bp, SPACELEFT(buf, bp), "%s: ", - shortenstring(CurHostName, MAXSHORTSTR)); + (void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, + shortenstring(CurHostName, MAXSHORTSTR), ": "); bp += strlen(bp); } - snprintf(bp, SPACELEFT(buf, bp), "%s", dnsmsg); + (void) sm_strlcpy(bp, dnsmsg, SPACELEFT(buf, bp)); return buf; } -#ifdef LDAPMAP +#if LDAPMAP if (errnum >= E_LDAPBASE) return ldap_err2string(errnum - E_LDAPBASE); #endif /* LDAPMAP */ #if HASSTRERROR - return strerror(errnum); + err = strerror(errnum); + if (err == NULL) + { + (void) sm_snprintf(buf, sizeof buf, "Error %d", errnum); + return buf; + } + return err; #else /* HASSTRERROR */ if (errnum > 0 && errnum < sys_nerr) return sys_errlist[errnum]; - (void) snprintf(buf, sizeof buf, "Error %d", errnum); + (void) sm_snprintf(buf, sizeof buf, "Error %d", errnum); return buf; #endif /* HASSTRERROR */ } diff --git a/contrib/sendmail/src/headers.c b/contrib/sendmail/src/headers.c index d6ddc72..efb4f3c 100644 --- a/contrib/sendmail/src/headers.c +++ b/contrib/sendmail/src/headers.c @@ -11,13 +11,11 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: headers.c,v 8.203.4.13 2001/05/03 17:24:06 gshapiro Exp $"; -#endif /* ! lint */ +#include <sendmail.h> /* $FreeBSD$ */ -#include <sendmail.h> +SM_RCSID("@(#)$Id: headers.c,v 8.266 2001/10/12 01:50:12 gshapiro Exp $") static size_t fix_mime_header __P((char *)); static int priencode __P((char *)); @@ -46,7 +44,7 @@ setupheaders() s->s_header.hi_ruleset = NULL; } } -/* +/* ** CHOMPHEADER -- process and save a header line. ** ** Called by collect, readcf, and readqf to deal with header lines. @@ -67,32 +65,32 @@ setupheaders() static struct hdrinfo NormalHeader = { NULL, 0, NULL }; -u_long +unsigned long chompheader(line, pflag, hdrp, e) char *line; int pflag; HDR **hdrp; register ENVELOPE *e; { - u_char mid = '\0'; + unsigned char mid = '\0'; register char *p; register HDR *h; HDR **hp; char *fname; char *fvalue; - bool cond = FALSE; + bool cond = false; bool dropfrom; bool headeronly; STAB *s; struct hdrinfo *hi; - bool nullheader = FALSE; + bool nullheader = false; BITMAP256 mopts; if (tTd(31, 6)) { - dprintf("chompheader: "); + sm_dprintf("chompheader: "); xputs(line); - dprintf("\n"); + sm_dprintf("\n"); } headeronly = hdrp != NULL; @@ -124,7 +122,7 @@ chompheader(line, pflag, hdrp, e) goto hse; } - mid = (u_char) *p++; + mid = (unsigned char) *p++; /* catch ?$abc? */ if (*p != '\0') @@ -142,7 +140,7 @@ chompheader(line, pflag, hdrp, e) goto hse; } - mid = (u_char)macid(p, NULL); + mid = (unsigned char) macid(p); if (bitset(0200, mid)) p += strlen(macname(mid)) + 2; else @@ -154,7 +152,6 @@ chompheader(line, pflag, hdrp, e) *q = '?'; goto hse; } - } else { @@ -167,7 +164,7 @@ chompheader(line, pflag, hdrp, e) } setbitn(bitidx(*p), mopts); - cond = TRUE; + cond = true; p++; } } @@ -198,7 +195,7 @@ hse: while (isascii(*p) && isspace(*p)) p++; if (*p == '\0') - nullheader = TRUE; + nullheader = true; /* security scan: long field names are end-of-header */ if (strlen(fname) > 100) @@ -224,6 +221,12 @@ hse: { *endp = '\0'; s = stab(fname, ST_HEADER, ST_ENTER); + if (LogLevel > 9 && + s->s_header.hi_ruleset != NULL) + sm_syslog(LOG_WARNING, NOQID, + "Warning: redefined ruleset for header=%s, old=%s, new=%s", + fname, + s->s_header.hi_ruleset, p); s->s_header.hi_ruleset = newstr(p); if (!strc) s->s_header.hi_flags |= H_STRIPCOMM; @@ -242,11 +245,12 @@ hse: if (tTd(31, 9)) { if (s == NULL) - dprintf("no header flags match\n"); + sm_dprintf("no header flags match\n"); else - dprintf("header match, flags=%lx, ruleset=%s\n", - hi->hi_flags, - hi->hi_ruleset == NULL ? "<NULL>" : hi->hi_ruleset); + sm_dprintf("header match, flags=%lx, ruleset=%s\n", + hi->hi_flags, + hi->hi_ruleset == NULL ? "<NULL>" + : hi->hi_ruleset); } /* see if this is a resent message */ @@ -283,7 +287,7 @@ hse: if (bitset(pflag, CHHDR_CHECK)) { - bool stripcom = FALSE; + bool stripcom = false; char *rs; /* no ruleset? look for default */ @@ -302,52 +306,70 @@ hse: stripcom = bitset(hi->hi_flags, H_STRIPCOMM); if (rs != NULL) { - int l; + int l, k; char qval[MAXNAME]; - char hlen[16]; - char *sp, *dp; - dp = qval; l = 0; - dp[l++] = '"'; - for (sp = fvalue; *sp != '\0' && l < MAXNAME - 3; sp++) + qval[l++] = '"'; + + /* - 3 to avoid problems with " at the end */ + for (k = 0; fvalue[k] != '\0' && l < MAXNAME - 3; k++) { - switch(*sp) + switch (fvalue[k]) { + /* XXX other control chars? */ case '\011': /* ht */ case '\012': /* nl */ case '\013': /* vt */ case '\014': /* np */ case '\015': /* cr */ - dp[l++] = ' '; + qval[l++] = ' '; break; case '"': - dp[l++] = '\\'; + qval[l++] = '\\'; /* FALLTHROUGH */ default: - dp[l++] = *sp; + qval[l++] = fvalue[k]; break; } } - dp[l++] = '"'; - dp[l++] = '\0'; - l = strlen(fvalue); - snprintf(hlen, sizeof hlen, "%d", l); - define(macid("{hdrlen}", NULL), newstr(hlen), e); - if (l >= MAXNAME) + qval[l++] = '"'; + qval[l] = '\0'; + k += strlen(fvalue + k); + if (k >= MAXNAME) { if (LogLevel > 9) sm_syslog(LOG_WARNING, e->e_id, "Warning: truncated header '%s' before check with '%s' len=%d max=%d", - fname, rs, l, MAXNAME - 1); + fname, rs, k, MAXNAME - 1); } - if ((sp = macvalue(macid("{currHeader}", NULL), e)) != - NULL) - sm_free(sp); - define(macid("{currHeader}", NULL), newstr(qval), e); - define(macid("{hdr_name}", NULL), newstr(fname), e); - (void) rscheck(rs, fvalue, NULL, e, stripcom, TRUE, 4, - NULL); + macdefine(&e->e_macro, A_TEMP, + macid("{currHeader}"), qval); + macdefine(&e->e_macro, A_TEMP, + macid("{hdr_name}"), fname); + + (void) sm_snprintf(qval, sizeof qval, "%d", k); + macdefine(&e->e_macro, A_TEMP, macid("{hdrlen}"), qval); +#if _FFR_HDR_TYPE + /* + ** XXX: h isn't set yet + ** If we really want to be precise then we have + ** to lookup the header (see below). + ** It's probably not worth the effort. + */ + + if (bitset(H_FROM, h->h_flags)) + macdefine(&e->e_macro, A_PERM, + macid("{addr_type}"), "h s"); + else if (bitset(H_RCPT, h->h_flags)) + macdefine(&e->e_macro, A_PERM, + macid("{addr_type}"), "h r"); + else +#endif /* _FFR_HDR_TYPE */ + macdefine(&e->e_macro, A_PERM, + macid("{addr_type}"), "h"); + (void) rscheck(rs, fvalue, NULL, e, stripcom, true, 3, + NULL, e->e_id); } } @@ -357,16 +379,16 @@ hse: ** insert the full name information in all circumstances. */ - dropfrom = FALSE; + dropfrom = false; p = "resent-from"; if (!bitset(EF_RESENT, e->e_flags)) p += 7; if (!bitset(pflag, CHHDR_DEF) && !headeronly && - !bitset(EF_QUEUERUN, e->e_flags) && strcasecmp(fname, p) == 0) + !bitset(EF_QUEUERUN, e->e_flags) && sm_strcasecmp(fname, p) == 0) { if (tTd(31, 2)) { - dprintf("comparing header from (%s) against default (%s or %s)\n", + sm_dprintf("comparing header from (%s) against default (%s or %s)\n", fvalue, e->e_from.q_paddr, e->e_from.q_user); } if (e->e_from.q_paddr != NULL && @@ -374,13 +396,13 @@ hse: bitnset(M_LOCALMAILER, e->e_from.q_mailer->m_flags) && (strcmp(fvalue, e->e_from.q_paddr) == 0 || strcmp(fvalue, e->e_from.q_user) == 0)) - dropfrom = TRUE; + dropfrom = true; } /* delete default value for this header */ for (hp = hdrp; (h = *hp) != NULL; hp = &h->h_link) { - if (strcasecmp(fname, h->h_field) == 0 && + if (sm_strcasecmp(fname, h->h_field) == 0 && !bitset(H_USER, h->h_flags) && !bitset(H_FORCE, h->h_flags)) { @@ -399,7 +421,7 @@ hse: if (!cond) { /* copy conditions from default case */ - memmove((char *)mopts, (char *)h->h_mflags, + memmove((char *) mopts, (char *) h->h_mflags, sizeof mopts); } h->h_macro = mid; @@ -407,9 +429,9 @@ hse: } /* create a new node */ - h = (HDR *) xalloc(sizeof *h); - h->h_field = newstr(fname); - h->h_value = newstr(fvalue); + h = (HDR *) sm_rpool_malloc_x(e->e_rpool, sizeof *h); + h->h_field = sm_rpool_strdup_x(e->e_rpool, fname); + h->h_value = sm_rpool_strdup_x(e->e_rpool, fvalue); h->h_link = NULL; memmove((char *) h->h_mflags, (char *) mopts, sizeof mopts); h->h_macro = mid; @@ -437,7 +459,7 @@ hse: return h->h_flags; } -/* +/* ** ADDHEADER -- add a header entry to the end of the queue. ** ** This bypasses the special checking of chompheader. @@ -446,7 +468,7 @@ hse: ** field -- the name of the header field. ** value -- the value of the field. ** flags -- flags to add to h_flags. -** hdrlist -- an indirect pointer to the header structure list. +** e -- envelope. ** ** Returns: ** none. @@ -456,15 +478,16 @@ hse: */ void -addheader(field, value, flags, hdrlist) +addheader(field, value, flags, e) char *field; char *value; int flags; - HDR **hdrlist; + ENVELOPE *e; { register HDR *h; STAB *s; HDR **hp; + HDR **hdrlist = &e->e_header; /* find info struct */ s = stab(field, ST_HEADER, ST_FIND); @@ -472,14 +495,14 @@ addheader(field, value, flags, hdrlist) /* find current place in list -- keep back pointer? */ for (hp = hdrlist; (h = *hp) != NULL; hp = &h->h_link) { - if (strcasecmp(field, h->h_field) == 0) + if (sm_strcasecmp(field, h->h_field) == 0) break; } /* allocate space for new header */ - h = (HDR *) xalloc(sizeof *h); + h = (HDR *) sm_rpool_malloc_x(e->e_rpool, sizeof *h); h->h_field = field; - h->h_value = newstr(value); + h->h_value = sm_rpool_strdup_x(e->e_rpool, value); h->h_link = *hp; h->h_flags = flags; if (s != NULL) @@ -488,7 +511,7 @@ addheader(field, value, flags, hdrlist) h->h_macro = '\0'; *hp = h; } -/* +/* ** HVALUE -- return value of a header. ** ** Only "real" fields (i.e., ones that have not been supplied @@ -516,12 +539,12 @@ hvalue(field, header) for (h = header; h != NULL; h = h->h_link) { if (!bitset(H_DEFAULT, h->h_flags) && - strcasecmp(h->h_field, field) == 0) + sm_strcasecmp(h->h_field, field) == 0) return h->h_value; } return NULL; } -/* +/* ** ISHEADER -- predicate telling if argument is a header. ** ** A line is a header if it has a single word followed by @@ -537,8 +560,8 @@ hvalue(field, header) ** h -- string to check for possible headerness. ** ** Returns: -** TRUE if h is a header. -** FALSE otherwise. +** true if h is a header. +** false otherwise. ** ** Side Effects: ** none. @@ -551,13 +574,13 @@ isheader(h) register char *s = h; if (s[0] == '-' && s[1] == '-') - return FALSE; + return false; while (*s > ' ' && *s != ':' && *s != '\0') s++; if (h == s) - return FALSE; + return false; /* following technically violates RFC822 */ while (isascii(*s) && isspace(*s)) @@ -565,7 +588,7 @@ isheader(h) return (*s == ':'); } -/* +/* ** EATHEADER -- run through the stored header and extract info. ** ** Parameters: @@ -574,6 +597,7 @@ isheader(h) ** message priority). This should not be set ** when reading a queue file because some info ** needed to compute the priority is wrong. +** log -- call logsender()? ** ** Returns: ** none. @@ -581,30 +605,29 @@ isheader(h) ** Side Effects: ** Sets a bunch of global variables from information ** in the collected header. -** Aborts the message if the hop count is exceeded. */ void -eatheader(e, full) +eatheader(e, full, log) register ENVELOPE *e; bool full; + bool log; { register HDR *h; register char *p; int hopcnt = 0; - char *msgid; char buf[MAXLINE]; /* ** Set up macros for possible expansion in headers. */ - define('f', e->e_sender, e); - define('g', e->e_sender, e); + macdefine(&e->e_macro, A_PERM, 'f', e->e_sender); + macdefine(&e->e_macro, A_PERM, 'g', e->e_sender); if (e->e_origrcpt != NULL && *e->e_origrcpt != '\0') - define('u', e->e_origrcpt, e); + macdefine(&e->e_macro, A_PERM, 'u', e->e_origrcpt); else - define('u', NULL, e); + macdefine(&e->e_macro, A_PERM, 'u', NULL); /* full name of from person */ p = hvalue("full-name", e->e_header); @@ -617,22 +640,23 @@ eatheader(e, full) ** as a comment so crackaddr() doesn't destroy ** the name portion of the address. */ - p = addquotes(p); + + p = addquotes(p, e->e_rpool); } - define('x', p, e); + macdefine(&e->e_macro, A_PERM, 'x', p); } if (tTd(32, 1)) - dprintf("----- collected header -----\n"); - msgid = NULL; + sm_dprintf("----- collected header -----\n"); + e->e_msgid = NULL; for (h = e->e_header; h != NULL; h = h->h_link) { if (tTd(32, 1)) - dprintf("%s: ", h->h_field); + sm_dprintf("%s: ", h->h_field); if (h->h_value == NULL) { if (tTd(32, 1)) - dprintf("<NULL>\n"); + sm_dprintf("<NULL>\n"); continue; } @@ -642,24 +666,24 @@ eatheader(e, full) { if (tTd(32, 1)) { - dprintf("("); + sm_dprintf("("); xputs(h->h_value); - dprintf(") "); + sm_dprintf(") "); } expand(h->h_value, buf, sizeof buf, e); if (buf[0] != '\0') { if (bitset(H_FROM, h->h_flags)) - expand(crackaddr(buf), buf, sizeof buf, e); - h->h_value = newstr(buf); + expand(crackaddr(buf), buf, sizeof buf, + e); + h->h_value = sm_rpool_strdup_x(e->e_rpool, buf); h->h_flags &= ~H_DEFAULT; } } - if (tTd(32, 1)) { xputs(h->h_value); - dprintf("\n"); + sm_dprintf("\n"); } /* count the number of times it has been processed */ @@ -669,14 +693,15 @@ eatheader(e, full) /* send to this person if we so desire */ if (GrabTo && bitset(H_RCPT, h->h_flags) && !bitset(H_DEFAULT, h->h_flags) && - (!bitset(EF_RESENT, e->e_flags) || bitset(H_RESENT, h->h_flags))) + (!bitset(EF_RESENT, e->e_flags) || + bitset(H_RESENT, h->h_flags))) { #if 0 int saveflags = e->e_flags; #endif /* 0 */ - (void) sendtolist(h->h_value, NULLADDR, - &e->e_sendqueue, 0, e); + (void) sendtolist(denlstring(h->h_value, true, false), + NULLADDR, &e->e_sendqueue, 0, e); #if 0 /* @@ -694,15 +719,15 @@ eatheader(e, full) p = "resent-message-id"; if (!bitset(EF_RESENT, e->e_flags)) p += 7; - if (strcasecmp(h->h_field, p) == 0) + if (sm_strcasecmp(h->h_field, p) == 0) { - msgid = h->h_value; - while (isascii(*msgid) && isspace(*msgid)) - msgid++; + e->e_msgid = h->h_value; + while (isascii(*e->e_msgid) && isspace(*e->e_msgid)) + e->e_msgid++; } } if (tTd(32, 1)) - dprintf("----------------------------\n"); + sm_dprintf("----------------------------\n"); /* if we are just verifying (that is, sendmail -t -bv), drop out now */ if (OpMode == MD_VERIFY) @@ -710,7 +735,11 @@ eatheader(e, full) /* store hop count */ if (hopcnt > e->e_hopcount) + { e->e_hopcount = hopcnt; + (void) sm_snprintf(buf, sizeof buf, "%d", e->e_hopcount); + macdefine(&e->e_macro, A_TEMP, 'c', buf); + } /* message priority */ p = hvalue("precedence", e->e_header); @@ -732,11 +761,11 @@ eatheader(e, full) if (p != NULL) { /* (this should be in the configuration file) */ - if (strcasecmp(p, "urgent") == 0) + if (sm_strcasecmp(p, "urgent") == 0) e->e_timeoutclass = TOC_URGENT; - else if (strcasecmp(p, "normal") == 0) + else if (sm_strcasecmp(p, "normal") == 0) e->e_timeoutclass = TOC_NORMAL; - else if (strcasecmp(p, "non-urgent") == 0) + else if (sm_strcasecmp(p, "non-urgent") == 0) e->e_timeoutclass = TOC_NONURGENT; } @@ -745,11 +774,11 @@ eatheader(e, full) if (p == NULL) p = hvalue("date", e->e_header); if (p != NULL) - define('a', p, e); + macdefine(&e->e_macro, A_PERM, 'a', p); /* check to see if this is a MIME message */ if ((e->e_bodytype != NULL && - strcasecmp(e->e_bodytype, "8BITMIME") == 0) || + sm_strcasecmp(e->e_bodytype, "8BITMIME") == 0) || hvalue("MIME-Version", e->e_header) != NULL) { e->e_flags |= EF_IS_MIME; @@ -787,9 +816,9 @@ eatheader(e, full) if (hi->hi_field != NULL) { if (tTd(32, 2)) - dprintf("eatheader: setsender(*%s == %s)\n", + sm_dprintf("eatheader: setsender(*%s == %s)\n", hi->hi_field, p); - setsender(p, e, NULL, '\0', TRUE); + setsender(p, e, NULL, '\0', true); } } @@ -797,11 +826,13 @@ eatheader(e, full) ** Log collection information. */ - if (bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4) - logsender(e, msgid); - e->e_flags &= ~EF_LOGSENDER; + if (log && bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4) + { + logsender(e, e->e_msgid); + e->e_flags &= ~EF_LOGSENDER; + } } -/* +/* ** LOGSENDER -- log sender information ** ** Parameters: @@ -826,6 +857,7 @@ logsender(e, msgid) char mbuf[MAXNAME + 1]; /* don't allow newlines in the message-id */ + /* XXX do we still need this? sm_syslog() replaces control chars */ if (msgid != NULL) { l = strlen(msgid); @@ -850,70 +882,59 @@ logsender(e, msgid) else { name = hbuf; - (void) snprintf(hbuf, sizeof hbuf, "%.80s", RealHostName); + (void) sm_snprintf(hbuf, sizeof hbuf, "%.80s", RealHostName); if (RealHostAddr.sa.sa_family != 0) { p = &hbuf[strlen(hbuf)]; - (void) snprintf(p, SPACELEFT(hbuf, p), " (%.100s)", - anynet_ntoa(&RealHostAddr)); + (void) sm_snprintf(p, SPACELEFT(hbuf, p), + " (%.100s)", + anynet_ntoa(&RealHostAddr)); } } /* some versions of syslog only take 5 printf args */ #if (SYSLOG_BUFSIZE) >= 256 sbp = sbuf; - snprintf(sbp, SPACELEFT(sbuf, sbp), - "from=%.200s, size=%ld, class=%d, nrcpts=%d", - e->e_from.q_paddr == NULL ? "<NONE>" : e->e_from.q_paddr, - e->e_msgsize, e->e_class, e->e_nrcpts); + (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), + "from=%.200s, size=%ld, class=%d, nrcpts=%d", + e->e_from.q_paddr == NULL ? "<NONE>" : e->e_from.q_paddr, + e->e_msgsize, e->e_class, e->e_nrcpts); sbp += strlen(sbp); if (msgid != NULL) { - snprintf(sbp, SPACELEFT(sbuf, sbp), ", msgid=%.100s", mbuf); + (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), + ", msgid=%.100s", mbuf); sbp += strlen(sbp); } if (e->e_bodytype != NULL) { - (void) snprintf(sbp, SPACELEFT(sbuf, sbp), ", bodytype=%.20s", - e->e_bodytype); + (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), + ", bodytype=%.20s", e->e_bodytype); sbp += strlen(sbp); } p = macvalue('r', e); if (p != NULL) { - (void) snprintf(sbp, SPACELEFT(sbuf, sbp), ", proto=%.20s", p); - sbp += strlen(sbp); - } - p = macvalue(macid("{daemon_name}", NULL), e); - if (p != NULL) - { - (void) snprintf(sbp, SPACELEFT(sbuf, sbp), ", daemon=%.20s", p); + (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), + ", proto=%.20s", p); sbp += strlen(sbp); } -# if SASL - p = macvalue(macid("{auth_type}", NULL), e); + p = macvalue(macid("{daemon_name}"), e); if (p != NULL) { - (void) snprintf(sbp, SPACELEFT(sbuf, sbp), ", mech=%.12s", p); + (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), + ", daemon=%.20s", p); sbp += strlen(sbp); } - p = macvalue(macid("{auth_author}", NULL), e); - if (p != NULL) - { - (void) snprintf(sbp, SPACELEFT(sbuf, sbp), ", auth=%.30s", p); - sbp += strlen(sbp); - } -# endif /* SASL */ - sm_syslog(LOG_INFO, e->e_id, - "%.850s, relay=%.100s", - sbuf, name); + sm_syslog(LOG_INFO, e->e_id, "%.850s, relay=%.100s", sbuf, name); #else /* (SYSLOG_BUFSIZE) >= 256 */ sm_syslog(LOG_INFO, e->e_id, "from=%s", e->e_from.q_paddr == NULL ? "<NONE>" - : shortenstring(e->e_from.q_paddr, 83)); + : shortenstring(e->e_from.q_paddr, + 83)); sm_syslog(LOG_INFO, e->e_id, "size=%ld, class=%ld, nrcpts=%d", e->e_msgsize, e->e_class, e->e_nrcpts); @@ -925,20 +946,22 @@ logsender(e, msgid) *sbp = '\0'; if (e->e_bodytype != NULL) { - snprintf(sbp, SPACELEFT(sbuf, sbp), "bodytype=%.20s, ", e->e_bodytype); + (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), + "bodytype=%.20s, ", e->e_bodytype); sbp += strlen(sbp); } p = macvalue('r', e); if (p != NULL) { - snprintf(sbp, SPACELEFT(sbuf, sbp), "proto=%.20s, ", p); + (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), + "proto=%.20s, ", p); sbp += strlen(sbp); } sm_syslog(LOG_INFO, e->e_id, "%.400srelay=%.100s", sbuf, name); #endif /* (SYSLOG_BUFSIZE) >= 256 */ } -/* +/* ** PRIENCODE -- encode external priority names into internal values. ** ** Parameters: @@ -959,14 +982,14 @@ priencode(p) for (i = 0; i < NumPriorities; i++) { - if (strcasecmp(p, Priorities[i].pri_name) == 0) + if (sm_strcasecmp(p, Priorities[i].pri_name) == 0) return Priorities[i].pri_val; } /* unknown priority */ return 0; } -/* +/* ** CRACKADDR -- parse an address and turn it into a macro ** ** This doesn't actually parse the address -- it just extracts @@ -1008,10 +1031,10 @@ crackaddr(addr) bool qmode; bool realqmode; bool skipping; - bool putgmac = FALSE; - bool quoteit = FALSE; - bool gotangle = FALSE; - bool gotcolon = FALSE; + bool putgmac = false; + bool quoteit = false; + bool gotangle = false; + bool gotcolon = false; register char *bp; char *buflim; char *bufhead; @@ -1019,7 +1042,7 @@ crackaddr(addr) static char buf[MAXNAME + 1]; if (tTd(33, 1)) - dprintf("crackaddr(%s)\n", addr); + sm_dprintf("crackaddr(%s)\n", addr); /* strip leading spaces */ while (*addr != '\0' && isascii(*addr) && isspace(*addr)) @@ -1035,7 +1058,7 @@ crackaddr(addr) p = addrhead = addr; copylev = anglelev = realanglelev = cmtlev = realcmtlev = 0; bracklev = 0; - qmode = realqmode = FALSE; + qmode = realqmode = false; while ((c = *p++) != '\0') { @@ -1055,7 +1078,7 @@ crackaddr(addr) { /* arrange to quote the address */ if (cmtlev <= 0 && !qmode) - quoteit = TRUE; + quoteit = true; if ((c = *p++) == '\0') { @@ -1140,7 +1163,7 @@ crackaddr(addr) if (*p == ':' || *p == '.') { if (cmtlev <= 0 && !qmode) - quoteit = TRUE; + quoteit = true; if (copylev > 0 && !skipping) { *bp++ = c; @@ -1150,7 +1173,7 @@ crackaddr(addr) goto putg; } - gotcolon = TRUE; + gotcolon = true; bp = bufhead; if (quoteit) @@ -1191,7 +1214,7 @@ crackaddr(addr) while (isascii(*p) && isspace(*p) && bp < buflim) *bp++ = *p++; copylev = 0; - putgmac = quoteit = FALSE; + putgmac = quoteit = false; bufhead = bp; addrhead = p; continue; @@ -1214,7 +1237,7 @@ crackaddr(addr) */ if (cmtlev <= 0 && !qmode) - quoteit = TRUE; + quoteit = true; } /* check for angle brackets */ @@ -1224,8 +1247,8 @@ crackaddr(addr) /* assume first of two angles is bogus */ if (gotangle) - quoteit = TRUE; - gotangle = TRUE; + quoteit = true; + gotangle = true; /* oops -- have to change our mind */ anglelev = 1; @@ -1267,7 +1290,7 @@ crackaddr(addr) *bp++ = c; } copylev = 0; - putgmac = quoteit = FALSE; + putgmac = quoteit = false; continue; } @@ -1287,7 +1310,7 @@ crackaddr(addr) /* syntax error: unmatched > */ if (copylev > 0) bp--; - quoteit = TRUE; + quoteit = true; continue; } if (copylev++ <= 0) @@ -1303,7 +1326,7 @@ crackaddr(addr) *bp++ = ' '; *bp++ = MACROEXPAND; *bp++ = 'g'; - putgmac = TRUE; + putgmac = true; } } @@ -1318,14 +1341,14 @@ crackaddr(addr) if (tTd(33, 1)) { - dprintf("crackaddr=>`"); + sm_dprintf("crackaddr=>`"); xputs(buf); - dprintf("'\n"); + sm_dprintf("'\n"); } return buf; } -/* +/* ** PUTHEADER -- put the header part of a message from the in-core copy ** ** Parameters: @@ -1341,13 +1364,6 @@ crackaddr(addr) ** none. */ -/* - * Macro for fast max (not available in e.g. DG/UX, 386/ix). - */ -#ifndef MAX -# define MAX(a,b) (((a)>(b))?(a):(b)) -#endif /* ! MAX */ - void putheader(mci, hdr, e, flags) register MCI *mci; @@ -1356,11 +1372,11 @@ putheader(mci, hdr, e, flags) int flags; { register HDR *h; - char buf[MAX(MAXLINE,BUFSIZ)]; + char buf[SM_MAX(MAXLINE,BUFSIZ)]; char obuf[MAXLINE]; if (tTd(34, 1)) - dprintf("--- putheader, mailer = %s ---\n", + sm_dprintf("--- putheader, mailer = %s ---\n", mci->mci_mailer->m_name); /* @@ -1375,10 +1391,11 @@ putheader(mci, hdr, e, flags) for (h = hdr; h != NULL; h = h->h_link) { register char *p = h->h_value; + char *q; if (tTd(34, 11)) { - dprintf(" %s: ", h->h_field); + sm_dprintf(" %s: ", h->h_field); xputs(p); } @@ -1389,7 +1406,7 @@ putheader(mci, hdr, e, flags) /* heuristic shortening of MIME fields to avoid MUA overflows */ if (MaxMimeFieldLength > 0 && wordinclass(h->h_field, - macid("{checkMIMEFieldHeaders}", NULL))) + macid("{checkMIMEFieldHeaders}"))) { size_t len; @@ -1400,15 +1417,15 @@ putheader(mci, hdr, e, flags) "Truncated MIME %s header due to field size (length = %ld) (possible attack)", h->h_field, (unsigned long) len); if (tTd(34, 11)) - dprintf(" truncated MIME %s header due to field size (length = %ld) (possible attack)\n", - h->h_field, - (unsigned long) len); + sm_dprintf(" truncated MIME %s header due to field size (length = %ld) (possible attack)\n", + h->h_field, + (unsigned long) len); } } if (MaxMimeHeaderLength > 0 && wordinclass(h->h_field, - macid("{checkMIMETextHeaders}", NULL))) + macid("{checkMIMETextHeaders}"))) { size_t len; @@ -1420,15 +1437,15 @@ putheader(mci, hdr, e, flags) "Truncated long MIME %s header (length = %ld) (possible attack)", h->h_field, (unsigned long) len); if (tTd(34, 11)) - dprintf(" truncated long MIME %s header (length = %ld) (possible attack)\n", - h->h_field, - (unsigned long) len); + sm_dprintf(" truncated long MIME %s header (length = %ld) (possible attack)\n", + h->h_field, + (unsigned long) len); } } if (MaxMimeHeaderLength > 0 && wordinclass(h->h_field, - macid("{checkMIMEHeaders}", NULL))) + macid("{checkMIMEHeaders}"))) { size_t len; @@ -1440,9 +1457,9 @@ putheader(mci, hdr, e, flags) "Truncated long MIME %s header (length = %ld) (possible attack)", h->h_field, (unsigned long) len); if (tTd(34, 11)) - dprintf(" truncated long MIME %s header (length = %ld) (possible attack)\n", - h->h_field, - (unsigned long) len); + sm_dprintf(" truncated long MIME %s header (length = %ld) (possible attack)\n", + h->h_field, + (unsigned long) len); } } @@ -1452,20 +1469,21 @@ putheader(mci, hdr, e, flags) ** MIME. If converting, add a new CTE header in ** mime8to7(). */ + if (bitset(H_CTE, h->h_flags) && bitset(MCIF_CVT8TO7|MCIF_CVT7TO8|MCIF_INMIME, mci->mci_flags) && !bitset(M87F_NO8TO7, flags)) { if (tTd(34, 11)) - dprintf(" (skipped (content-transfer-encoding))\n"); + sm_dprintf(" (skipped (content-transfer-encoding))\n"); continue; } if (bitset(MCIF_INMIME, mci->mci_flags)) { if (tTd(34, 11)) - dprintf("\n"); + sm_dprintf("\n"); put_vanilla_header(h, p, mci); continue; } @@ -1473,10 +1491,11 @@ putheader(mci, hdr, e, flags) if (bitset(H_CHECK|H_ACHECK, h->h_flags) && !bitintersect(h->h_mflags, mci->mci_mailer->m_flags) && (h->h_macro == '\0' || - macvalue(bitidx(h->h_macro), e) == NULL)) + (q = macvalue(bitidx(h->h_macro), e)) == NULL || + *q == '\0')) { if (tTd(34, 11)) - dprintf(" (skipped)\n"); + sm_dprintf(" (skipped)\n"); continue; } @@ -1484,7 +1503,7 @@ putheader(mci, hdr, e, flags) if (bitset(H_RESENT, h->h_flags) && !bitset(EF_RESENT, e->e_flags)) { if (tTd(34, 11)) - dprintf(" (skipped (resent))\n"); + sm_dprintf(" (skipped (resent))\n"); continue; } @@ -1493,7 +1512,7 @@ putheader(mci, hdr, e, flags) (RrtImpliesDsn || bitset(EF_NORECEIPT, e->e_flags))) { if (tTd(34, 11)) - dprintf(" (skipped (receipt))\n"); + sm_dprintf(" (skipped (receipt))\n"); continue; } @@ -1506,7 +1525,7 @@ putheader(mci, hdr, e, flags) if (*p == '\0') { if (tTd(34, 11)) - dprintf(" (skipped -- null value)\n"); + sm_dprintf(" (skipped -- null value)\n"); continue; } } @@ -1517,20 +1536,20 @@ putheader(mci, hdr, e, flags) if (bitset(EF_DELETE_BCC, e->e_flags)) { if (tTd(34, 11)) - dprintf(" (skipped -- bcc)\n"); + sm_dprintf(" (skipped -- bcc)\n"); } else { /* no other recipient headers: truncate value */ - (void) snprintf(obuf, sizeof obuf, "%s:", - h->h_field); + (void) sm_strlcpyn(obuf, sizeof obuf, 2, + h->h_field, ":"); putline(obuf, mci); } continue; } if (tTd(34, 11)) - dprintf("\n"); + sm_dprintf("\n"); if (bitset(H_FROM|H_RCPT, h->h_flags)) { @@ -1538,7 +1557,7 @@ putheader(mci, hdr, e, flags) bool oldstyle = bitset(EF_OLDSTYLE, e->e_flags); if (bitset(H_FROM, h->h_flags)) - oldstyle = FALSE; + oldstyle = false; commaize(h, p, oldstyle, mci, e); } else @@ -1563,9 +1582,9 @@ putheader(mci, hdr, e, flags) putline("MIME-Version: 1.0", mci); if (hvalue("Content-Type", e->e_header) == NULL) { - snprintf(obuf, sizeof obuf, - "Content-Type: text/plain; charset=%s", - defcharset(e)); + (void) sm_snprintf(obuf, sizeof obuf, + "Content-Type: text/plain; charset=%s", + defcharset(e)); putline(obuf, mci); } if (hvalue("Content-Transfer-Encoding", e->e_header) == NULL) @@ -1573,7 +1592,7 @@ putheader(mci, hdr, e, flags) } #endif /* MIME8TO7 */ } -/* +/* ** PUT_VANILLA_HEADER -- output a fairly ordinary header ** ** Parameters: @@ -1599,34 +1618,34 @@ put_vanilla_header(h, v, mci) putflags = PXLF_HEADER; if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags)) putflags |= PXLF_STRIP8BIT; - (void) snprintf(obuf, sizeof obuf, "%.200s: ", h->h_field); + (void) sm_snprintf(obuf, sizeof obuf, "%.200s: ", h->h_field); obp = obuf + strlen(obuf); while ((nlp = strchr(v, '\n')) != NULL) { int l; l = nlp - v; - if (SPACELEFT(obuf, obp) - 1 < (size_t)l) + if (SPACELEFT(obuf, obp) - 1 < (size_t) l) l = SPACELEFT(obuf, obp) - 1; - snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v); + (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", l, v); putxline(obuf, strlen(obuf), mci, putflags); v += l + 1; obp = obuf; if (*v != ' ' && *v != '\t') *obp++ = ' '; } - snprintf(obp, SPACELEFT(obuf, obp), "%.*s", - (int) sizeof obuf - (obp - obuf) - 1, v); + (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", + (int) (SPACELEFT(obuf, obp) - 1), v); putxline(obuf, strlen(obuf), mci, putflags); } -/* +/* ** COMMAIZE -- output a header field, making a comma-translated list. ** ** Parameters: ** h -- the header field to output. ** p -- the value to put in it. -** oldstyle -- TRUE if this is an old style header. +** oldstyle -- true if this is an old style header. ** mci -- the connection information. ** e -- the envelope containing the message. ** @@ -1648,7 +1667,7 @@ commaize(h, p, oldstyle, mci, e) register char *obp; int opos; int omax; - bool firstone = TRUE; + bool firstone = true; int putflags = PXLF_HEADER; char obuf[MAXLINE + 3]; @@ -1658,13 +1677,14 @@ commaize(h, p, oldstyle, mci, e) */ if (tTd(14, 2)) - dprintf("commaize(%s: %s)\n", h->h_field, p); + sm_dprintf("commaize(%s: %s)\n", h->h_field, p); if (bitnset(M_7BITHDRS, mci->mci_mailer->m_flags)) putflags |= PXLF_STRIP8BIT; obp = obuf; - (void) snprintf(obp, SPACELEFT(obuf, obp), "%.200s: ", h->h_field); + (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.200s: ", + h->h_field); opos = strlen(h->h_field) + 2; if (opos > 202) opos = 202; @@ -1715,7 +1735,7 @@ commaize(h, p, oldstyle, mci, e) p = oldp; break; } - p += *p == '@' ? 1 : 2; + ++p; while (*p != '\0' && isascii(*p) && isspace(*p)) p++; } @@ -1740,7 +1760,7 @@ commaize(h, p, oldstyle, mci, e) { char *q; - q = udbsender(name); + q = udbsender(name, e->e_rpool); if (q != NULL) name = q; } @@ -1752,14 +1772,14 @@ commaize(h, p, oldstyle, mci, e) *p = savechar; continue; } - name = denlstring(name, FALSE, TRUE); + name = denlstring(name, false, true); /* ** record data progress so DNS timeouts ** don't cause DATA timeouts */ - DataProgress = TRUE; + DataProgress = true; /* output the name with nice formatting */ opos += strlen(name); @@ -1767,35 +1787,36 @@ commaize(h, p, oldstyle, mci, e) opos += 2; if (opos > omax && !firstone) { - snprintf(obp, SPACELEFT(obuf, obp), ",\n"); + (void) sm_strlcpy(obp, ",\n", SPACELEFT(obuf, obp)); putxline(obuf, strlen(obuf), mci, putflags); obp = obuf; - (void) strlcpy(obp, " ", sizeof obp); + (void) sm_strlcpy(obp, " ", sizeof obp); opos = strlen(obp); obp += opos; opos += strlen(name); } else if (!firstone) { - snprintf(obp, SPACELEFT(obuf, obp), ", "); + (void) sm_strlcpy(obp, ", ", SPACELEFT(obuf, obp)); obp += 2; } while ((c = *name++) != '\0' && obp < &obuf[MAXLINE]) *obp++ = c; - firstone = FALSE; + firstone = false; *p = savechar; } *obp = '\0'; putxline(obuf, strlen(obuf), mci, putflags); } -/* +/* ** COPYHEADER -- copy header list ** ** This routine is the equivalent of newstr for header lists ** ** Parameters: ** header -- list of header structures to copy. +** rpool -- resource pool, or NULL ** ** Returns: ** a copy of 'header'. @@ -1805,8 +1826,9 @@ commaize(h, p, oldstyle, mci, e) */ HDR * -copyheader(header) +copyheader(header, rpool) register HDR *header; + SM_RPOOL_T *rpool; { register HDR *newhdr; HDR *ret; @@ -1814,7 +1836,7 @@ copyheader(header) while (header != NULL) { - newhdr = (HDR *) xalloc(sizeof *newhdr); + newhdr = (HDR *) sm_rpool_malloc_x(rpool, sizeof *newhdr); STRUCTCOPY(*header, *newhdr); *tail = newhdr; tail = &newhdr->h_link; @@ -1824,7 +1846,7 @@ copyheader(header) return ret; } -/* +/* ** FIX_MIME_HEADER -- possibly truncate/rebalance parameters in a MIME header ** ** Run through all of the parameters of a MIME header and diff --git a/contrib/sendmail/src/mailq.1 b/contrib/sendmail/src/mailq.1 index 8a73342..9d9fe09 100644 --- a/contrib/sendmail/src/mailq.1 +++ b/contrib/sendmail/src/mailq.1 @@ -9,11 +9,11 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: mailq.1,v 8.14.28.3 2000/12/14 23:08:15 gshapiro Exp $ +.\" $Id: mailq.1,v 8.18 2000/12/23 19:37:48 ca Exp $ .\" .\" $FreeBSD$ .\" -.TH MAILQ 1 "$Date: 2000/12/14 23:08:15 $" +.TH MAILQ 1 "$Date: 2000/12/23 19:37:48 $" .SH NAME mailq \- print the mail queue @@ -60,6 +60,8 @@ indicating the ``controlling user'' information; this shows who will own any programs that are executed on behalf of this message and the name of the alias this command expanded from, if any. +Moreover, status messages for each recipient are printed +if available. .PP The .B mailq diff --git a/contrib/sendmail/src/mci.c b/contrib/sendmail/src/mci.c index c24117f..f6c2523 100644 --- a/contrib/sendmail/src/mci.c +++ b/contrib/sendmail/src/mci.c @@ -11,14 +11,11 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: mci.c,v 8.133.10.8 2001/05/03 17:24:10 gshapiro Exp $"; -#endif /* ! lint */ - /* $FreeBSD$ */ #include <sendmail.h> +SM_RCSID("@(#)$Id: mci.c,v 8.202 2001/11/05 22:12:17 ca Exp $") #if NETINET || NETINET6 # include <arpa/inet.h> @@ -31,7 +28,7 @@ static int mci_generate_persistent_path __P((const char *, char *, static bool mci_load_persistent __P((MCI *)); static void mci_uncache __P((MCI **, bool)); static int mci_lock_host_statfile __P((MCI *)); -static int mci_read_persistent __P((FILE *, MCI *)); +static int mci_read_persistent __P((SM_FILE_T *, MCI *)); /* ** Mail Connection Information (MCI) Caching Module. @@ -66,7 +63,7 @@ static int mci_read_persistent __P((FILE *, MCI *)); static MCI **MciCache; /* the open connection cache */ -/* +/* ** MCI_CACHE -- enter a connection structure into the open connection cache ** ** This may cause something else to be flushed. @@ -105,21 +102,21 @@ mci_cache(mci) /* otherwise we may have to clear the slot */ if (*mcislot != NULL) - mci_uncache(mcislot, TRUE); + mci_uncache(mcislot, true); if (tTd(42, 5)) - dprintf("mci_cache: caching %lx (%s) in slot %d\n", - (u_long) mci, mci->mci_host, - (int)(mcislot - MciCache)); + sm_dprintf("mci_cache: caching %p (%s) in slot %d\n", + mci, mci->mci_host, (int) (mcislot - MciCache)); if (tTd(91, 100)) sm_syslog(LOG_DEBUG, CurEnv->e_id, "mci_cache: caching %lx (%.100s) in slot %d", - (u_long) mci, mci->mci_host, mcislot - MciCache); + (unsigned long) mci, mci->mci_host, + (int) (mcislot - MciCache)); *mcislot = mci; mci->mci_flags |= MCIF_CACHED; } -/* +/* ** MCI_SCAN -- scan the cache, flush junk, and return best slot ** ** Parameters: @@ -147,7 +144,7 @@ mci_scan(savemci) if (MciCache == NULL) { /* first call */ - MciCache = (MCI **) xalloc(MaxMciCache * sizeof *MciCache); + MciCache = (MCI **) sm_pmalloc_x(MaxMciCache * sizeof *MciCache); memset((char *) MciCache, '\0', MaxMciCache * sizeof *MciCache); return &MciCache[0]; } @@ -172,7 +169,7 @@ mci_scan(savemci) bestmci = &MciCache[i]; /* close it */ - mci_uncache(bestmci, TRUE); + mci_uncache(bestmci, true); continue; } if (*bestmci == NULL) @@ -182,15 +179,15 @@ mci_scan(savemci) } return bestmci; } -/* +/* ** MCI_UNCACHE -- remove a connection from a slot. ** ** May close a connection. ** ** Parameters: ** mcislot -- the slot to empty. -** doquit -- if TRUE, send QUIT protocol on this connection. -** if FALSE, we are assumed to be in a forked child; +** doquit -- if true, send QUIT protocol on this connection. +** if false, we are assumed to be in a forked child; ** all we want to do is close the file(s). ** ** Returns: @@ -215,17 +212,16 @@ mci_uncache(mcislot, doquit) mci_unlock_host(mci); if (tTd(42, 5)) - dprintf("mci_uncache: uncaching %lx (%s) from slot %d (%d)\n", - (u_long) mci, mci->mci_host, - (int)(mcislot - MciCache), doquit); + sm_dprintf("mci_uncache: uncaching %p (%s) from slot %d (%d)\n", + mci, mci->mci_host, (int) (mcislot - MciCache), + doquit); if (tTd(91, 100)) sm_syslog(LOG_DEBUG, CurEnv->e_id, "mci_uncache: uncaching %lx (%.100s) from slot %d (%d)", - (u_long) mci, mci->mci_host, - mcislot - MciCache, doquit); + (unsigned long) mci, mci->mci_host, + (int) (mcislot - MciCache), doquit); mci->mci_deliveries = 0; -#if SMTP if (doquit) { message("Closing connection to %s", mci->mci_host); @@ -235,30 +231,45 @@ mci_uncache(mcislot, doquit) /* only uses the envelope to flush the transcript file */ if (mci->mci_state != MCIS_CLOSED) smtpquit(mci->mci_mailer, mci, &BlankEnvelope); -# ifdef XLA +#if XLA xla_host_end(mci->mci_host); -# endif /* XLA */ +#endif /* XLA */ } else -#endif /* SMTP */ { if (mci->mci_in != NULL) - (void) fclose(mci->mci_in); + (void) sm_io_close(mci->mci_in, SM_TIME_DEFAULT); if (mci->mci_out != NULL) - (void) fclose(mci->mci_out); + (void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT); mci->mci_in = mci->mci_out = NULL; mci->mci_state = MCIS_CLOSED; mci->mci_exitstat = EX_OK; mci->mci_errno = 0; mci->mci_flags = 0; + + mci->mci_retryrcpt = false; + mci->mci_tolist = NULL; +#if PIPELINING + mci->mci_okrcpts = 0; +#endif /* PIPELINING */ + } + + SM_FREE_CLR(mci->mci_status); + SM_FREE_CLR(mci->mci_rstatus); + SM_FREE_CLR(mci->mci_heloname); + if (mci->mci_rpool != NULL) + { + sm_rpool_free(mci->mci_rpool); + mci->mci_macro.mac_rpool = NULL; + mci->mci_rpool = NULL; } } -/* +/* ** MCI_FLUSH -- flush the entire cache ** ** Parameters: -** doquit -- if TRUE, send QUIT protocol. -** if FALSE, just close the connection. +** doquit -- if true, send QUIT protocol. +** if false, just close the connection. ** allbut -- but leave this one open. ** ** Returns: @@ -281,8 +292,15 @@ mci_flush(doquit, allbut) mci_uncache(&MciCache[i], doquit); } } -/* +/* ** MCI_GET -- get information about a particular host +** +** Parameters: +** host -- host to look for. +** m -- mailer. +** +** Returns: +** mci for this host (might be new). */ MCI * @@ -292,13 +310,10 @@ mci_get(host, m) { register MCI *mci; register STAB *s; - -#if DAEMON extern SOCKADDR CurHostAddr; /* clear CurHostAddr so we don't get a bogus address with this name */ memset(&CurHostAddr, '\0', sizeof CurHostAddr); -#endif /* DAEMON */ /* clear out any expired connections */ (void) mci_scan(NULL); @@ -309,8 +324,21 @@ mci_get(host, m) s = stab(host, ST_MCI + m->m_mno, ST_ENTER); mci = &s->s_mci; + /* initialize per-message data */ + mci->mci_retryrcpt = false; + mci->mci_tolist = NULL; +#if PIPELINING + mci->mci_okrcpts = 0; +#endif /* PIPELINING */ + + if (mci->mci_rpool == NULL) + mci->mci_rpool = sm_rpool_new_x(NULL); + + if (mci->mci_macro.mac_rpool == NULL) + mci->mci_macro.mac_rpool = mci->mci_rpool; + /* - ** We don't need to load the peristent data if we have data + ** We don't need to load the persistent data if we have data ** already loaded in the cache. */ @@ -319,7 +347,7 @@ mci_get(host, m) !mci_load_persistent(mci)) { if (tTd(42, 2)) - dprintf("mci_get(%s %s): lock failed\n", + sm_dprintf("mci_get(%s %s): lock failed\n", host, m->m_name); mci->mci_exitstat = EX_TEMPFAIL; mci->mci_state = MCIS_CLOSED; @@ -329,12 +357,11 @@ mci_get(host, m) if (tTd(42, 2)) { - dprintf("mci_get(%s %s): mci_state=%d, _flags=%lx, _exitstat=%d, _errno=%d\n", + sm_dprintf("mci_get(%s %s): mci_state=%d, _flags=%lx, _exitstat=%d, _errno=%d\n", host, m->m_name, mci->mci_state, mci->mci_flags, mci->mci_exitstat, mci->mci_errno); } -#if SMTP if (mci->mci_state == MCIS_OPEN) { /* poke the connection to see if it's still alive */ @@ -347,19 +374,17 @@ mci_get(host, m) mci->mci_exitstat = EX_OK; mci->mci_state = MCIS_CLOSED; } -# if DAEMON else { - /* get peer host address for logging reasons only */ + /* get peer host address */ /* (this should really be in the mci struct) */ SOCKADDR_LEN_T socklen = sizeof CurHostAddr; - (void) getpeername(fileno(mci->mci_in), + (void) getpeername(sm_io_getinfo(mci->mci_in, + SM_IO_WHAT_FD, NULL), (struct sockaddr *) &CurHostAddr, &socklen); } -# endif /* DAEMON */ } -#endif /* SMTP */ if (mci->mci_state == MCIS_CLOSED) { time_t now = curtime(); @@ -375,8 +400,40 @@ mci_get(host, m) return mci; } -/* +/* +** MCI_NEW -- allocate new MCI structure +** +** Parameters: +** rpool -- if non-NULL: allocate from that rpool. +** +** Returns: +** mci (new). +*/ + +MCI * +mci_new(rpool) + SM_RPOOL_T *rpool; +{ + register MCI *mci; + + if (rpool == NULL) + mci = (MCI *) sm_malloc_x(sizeof *mci); + else + mci = (MCI *) sm_rpool_malloc_x(rpool, sizeof *mci); + memset((char *) mci, '\0', sizeof *mci); + mci->mci_rpool = sm_rpool_new_x(NULL); + mci->mci_macro.mac_rpool = mci->mci_rpool; + return mci; +} +/* ** MCI_MATCH -- check connection cache for a particular host +** +** Parameters: +** host -- host to look for. +** m -- mailer. +** +** Returns: +** true iff open connection exists. */ bool @@ -388,17 +445,15 @@ mci_match(host, m) register STAB *s; if (m->m_mno < 0 || m->m_mno > MAXMAILERS) - return FALSE; + return false; s = stab(host, ST_MCI + m->m_mno, ST_FIND); if (s == NULL) - return FALSE; + return false; mci = &s->s_mci; - if (mci->mci_state == MCIS_OPEN) - return TRUE; - return FALSE; + return mci->mci_state == MCIS_OPEN; } -/* +/* ** MCI_SETSTAT -- set status codes in MCI structure. ** ** Parameters: @@ -422,14 +477,15 @@ mci_setstat(mci, xstat, dstat, rstat) if (xstat != EX_NOTSTICKY && xstat != EX_PROTOCOL) mci->mci_exitstat = xstat; - mci->mci_status = dstat; - if (mci->mci_rstatus != NULL) - sm_free(mci->mci_rstatus); + SM_FREE_CLR(mci->mci_status); + if (dstat != NULL) + mci->mci_status = sm_strdup_x(dstat); + + SM_FREE_CLR(mci->mci_rstatus); if (rstat != NULL) - rstat = newstr(rstat); - mci->mci_rstatus = rstat; + mci->mci_rstatus = sm_strdup_x(rstat); } -/* +/* ** MCI_DUMP -- dump the contents of an MCI structure. ** ** Parameters: @@ -450,7 +506,6 @@ struct mcifbits static struct mcifbits MciFlags[] = { { MCIF_VALID, "VALID" }, - { MCIF_TEMP, "TEMP" }, { MCIF_CACHED, "CACHED" }, { MCIF_ESMTP, "ESMTP" }, { MCIF_EXPN, "EXPN" }, @@ -464,10 +519,18 @@ static struct mcifbits MciFlags[] = { MCIF_8BITOK, "8BITOK" }, { MCIF_CVT7TO8, "CVT7TO8" }, { MCIF_INMIME, "INMIME" }, + { MCIF_AUTH, "AUTH" }, + { MCIF_AUTHACT, "AUTHACT" }, + { MCIF_ENHSTAT, "ENHSTAT" }, + { MCIF_PIPELINED, "PIPELINED" }, +#if STARTTLS + { MCIF_TLS, "TLS" }, + { MCIF_TLSACT, "TLSACT" }, +#endif /* STARTTLS */ + { MCIF_DLVR_BY, "DLVR_BY" }, { 0, NULL } }; - void mci_dump(mci, logit) register MCI *mci; @@ -479,14 +542,14 @@ mci_dump(mci, logit) sep = logit ? " " : "\n\t"; p = buf; - snprintf(p, SPACELEFT(buf, p), "MCI@%lx: ", (u_long) mci); + (void) sm_snprintf(p, SPACELEFT(buf, p), "MCI@%p: ", mci); p += strlen(p); if (mci == NULL) { - snprintf(p, SPACELEFT(buf, p), "NULL"); + (void) sm_snprintf(p, SPACELEFT(buf, p), "NULL"); goto printit; } - snprintf(p, SPACELEFT(buf, p), "flags=%lx", mci->mci_flags); + (void) sm_snprintf(p, SPACELEFT(buf, p), "flags=%lx", mci->mci_flags); p += strlen(p); if (mci->mci_flags != 0) { @@ -497,40 +560,39 @@ mci_dump(mci, logit) { if (!bitset(f->mcif_bit, mci->mci_flags)) continue; - snprintf(p, SPACELEFT(buf, p), "%s,", f->mcif_name); + (void) sm_strlcpyn(p, SPACELEFT(buf, p), 2, + f->mcif_name, ","); p += strlen(p); } p[-1] = '>'; } - snprintf(p, SPACELEFT(buf, p), + + /* Note: sm_snprintf() takes care of NULL arguments for %s */ + (void) sm_snprintf(p, SPACELEFT(buf, p), ",%serrno=%d, herrno=%d, exitstat=%d, state=%d, pid=%d,%s", sep, mci->mci_errno, mci->mci_herrno, mci->mci_exitstat, mci->mci_state, (int) mci->mci_pid, sep); p += strlen(p); - snprintf(p, SPACELEFT(buf, p), + (void) sm_snprintf(p, SPACELEFT(buf, p), "maxsize=%ld, phase=%s, mailer=%s,%s", - mci->mci_maxsize, - mci->mci_phase == NULL ? "NULL" : mci->mci_phase, + mci->mci_maxsize, mci->mci_phase, mci->mci_mailer == NULL ? "NULL" : mci->mci_mailer->m_name, sep); p += strlen(p); - snprintf(p, SPACELEFT(buf, p), + (void) sm_snprintf(p, SPACELEFT(buf, p), "status=%s, rstatus=%s,%s", - mci->mci_status == NULL ? "NULL" : mci->mci_status, - mci->mci_rstatus == NULL ? "NULL" : mci->mci_rstatus, - sep); + mci->mci_status, mci->mci_rstatus, sep); p += strlen(p); - snprintf(p, SPACELEFT(buf, p), + (void) sm_snprintf(p, SPACELEFT(buf, p), "host=%s, lastuse=%s", - mci->mci_host == NULL ? "NULL" : mci->mci_host, - ctime(&mci->mci_lastuse)); + mci->mci_host, ctime(&mci->mci_lastuse)); printit: if (logit) sm_syslog(LOG_DEBUG, CurEnv->e_id, "%.1000s", buf); else - printf("%s\n", buf); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s\n", buf); } -/* +/* ** MCI_DUMP_ALL -- print the entire MCI cache ** ** Parameters: @@ -553,7 +615,7 @@ mci_dump_all(logit) for (i = 0; i < MaxMciCache; i++) mci_dump(MciCache[i], logit); } -/* +/* ** MCI_LOCK_HOST -- Lock host while sending. ** ** If we are contacting a host, we'll need to @@ -561,7 +623,7 @@ mci_dump_all(logit) ** file, and if we want to do that, we ought to have ** locked it. This has the (according to some) ** desirable effect of serializing connectivity with -** remote hosts -- i.e.: one connection to a give +** remote hosts -- i.e.: one connection to a given ** host at a time. ** ** Parameters: @@ -579,7 +641,7 @@ mci_lock_host(mci) if (mci == NULL) { if (tTd(56, 1)) - dprintf("mci_lock_host: NULL mci\n"); + sm_dprintf("mci_lock_host: NULL mci\n"); return EX_OK; } @@ -601,15 +663,16 @@ mci_lock_host_statfile(mci) return EX_OK; if (tTd(56, 2)) - dprintf("mci_lock_host: attempting to lock %s\n", - mci->mci_host); + sm_dprintf("mci_lock_host: attempting to lock %s\n", + mci->mci_host); - if (mci_generate_persistent_path(mci->mci_host, fname, sizeof fname, TRUE) < 0) + if (mci_generate_persistent_path(mci->mci_host, fname, sizeof fname, + true) < 0) { /* of course this should never happen */ if (tTd(56, 2)) - dprintf("mci_lock_host: Failed to generate host path for %s\n", - mci->mci_host); + sm_dprintf("mci_lock_host: Failed to generate host path for %s\n", + mci->mci_host); retVal = EX_TEMPFAIL; goto cleanup; @@ -620,30 +683,30 @@ mci_lock_host_statfile(mci) if (mci->mci_statfile == NULL) { - syserr("mci_lock_host: cannot create host lock file %s", - fname); + syserr("mci_lock_host: cannot create host lock file %s", fname); goto cleanup; } - if (!lockfile(fileno(mci->mci_statfile), fname, "", LOCK_EX|LOCK_NB)) + if (!lockfile(sm_io_getinfo(mci->mci_statfile, SM_IO_WHAT_FD, NULL), + fname, "", LOCK_EX|LOCK_NB)) { if (tTd(56, 2)) - dprintf("mci_lock_host: couldn't get lock on %s\n", + sm_dprintf("mci_lock_host: couldn't get lock on %s\n", fname); - (void) fclose(mci->mci_statfile); + (void) sm_io_close(mci->mci_statfile, SM_TIME_DEFAULT); mci->mci_statfile = NULL; retVal = EX_TEMPFAIL; goto cleanup; } if (tTd(56, 12) && mci->mci_statfile != NULL) - dprintf("mci_lock_host: Sanity check -- lock is good\n"); + sm_dprintf("mci_lock_host: Sanity check -- lock is good\n"); cleanup: errno = save_errno; return retVal; } -/* +/* ** MCI_UNLOCK_HOST -- unlock host ** ** Clean up the lock on a host, close the file, let @@ -665,7 +728,7 @@ mci_unlock_host(mci) if (mci == NULL) { if (tTd(56, 1)) - dprintf("mci_unlock_host: NULL mci\n"); + sm_dprintf("mci_unlock_host: NULL mci\n"); return; } @@ -675,37 +738,35 @@ mci_unlock_host(mci) if (!SingleThreadDelivery && mci_lock_host_statfile(mci) == EX_TEMPFAIL) { if (tTd(56, 1)) - dprintf("mci_unlock_host: stat file already locked\n"); + sm_dprintf("mci_unlock_host: stat file already locked\n"); } else { if (tTd(56, 2)) - dprintf("mci_unlock_host: store prior to unlock\n"); - + sm_dprintf("mci_unlock_host: store prior to unlock\n"); mci_store_persistent(mci); } if (mci->mci_statfile != NULL) { - (void) fclose(mci->mci_statfile); + (void) sm_io_close(mci->mci_statfile, SM_TIME_DEFAULT); mci->mci_statfile = NULL; } errno = save_errno; } -/* +/* ** MCI_LOAD_PERSISTENT -- load persistent host info ** ** Load information about host that is kept ** in common for all running sendmails. ** ** Parameters: -** mci -- the host/connection to load persistent info -** for. +** mci -- the host/connection to load persistent info for. ** ** Returns: -** TRUE -- lock was successful -** FALSE -- lock failed +** true -- lock was successful +** false -- lock failed */ static bool @@ -713,33 +774,34 @@ mci_load_persistent(mci) MCI *mci; { int save_errno = errno; - bool locked = TRUE; - FILE *fp; + bool locked = true; + SM_FILE_T *fp; char fname[MAXPATHLEN + 1]; if (mci == NULL) { if (tTd(56, 1)) - dprintf("mci_load_persistent: NULL mci\n"); - return TRUE; + sm_dprintf("mci_load_persistent: NULL mci\n"); + return true; } if (IgnoreHostStatus || HostStatDir == NULL || mci->mci_host == NULL) - return TRUE; + return true; /* Already have the persistent information in memory */ if (SingleThreadDelivery && mci->mci_statfile != NULL) - return TRUE; + return true; if (tTd(56, 1)) - dprintf("mci_load_persistent: Attempting to load persistent information for %s\n", - mci->mci_host); + sm_dprintf("mci_load_persistent: Attempting to load persistent information for %s\n", + mci->mci_host); - if (mci_generate_persistent_path(mci->mci_host, fname, sizeof fname, FALSE) < 0) + if (mci_generate_persistent_path(mci->mci_host, fname, sizeof fname, + false) < 0) { /* Not much we can do if the file isn't there... */ if (tTd(56, 1)) - dprintf("mci_load_persistent: Couldn't generate host path\n"); + sm_dprintf("mci_load_persistent: Couldn't generate host path\n"); goto cleanup; } @@ -749,26 +811,28 @@ mci_load_persistent(mci) { /* I can't think of any reason this should ever happen */ if (tTd(56, 1)) - dprintf("mci_load_persistent: open(%s): %s\n", - fname, errstring(errno)); + sm_dprintf("mci_load_persistent: open(%s): %s\n", + fname, sm_errstring(errno)); goto cleanup; } FileName = fname; - locked = lockfile(fileno(fp), fname, "", LOCK_SH|LOCK_NB); + locked = lockfile(sm_io_getinfo(fp, SM_IO_WHAT_FD, NULL), fname, "", + LOCK_SH|LOCK_NB); if (locked) { (void) mci_read_persistent(fp, mci); - (void) lockfile(fileno(fp), fname, "", LOCK_UN); + (void) lockfile(sm_io_getinfo(fp, SM_IO_WHAT_FD, NULL), fname, + "", LOCK_UN); } FileName = NULL; - (void) fclose(fp); + (void) sm_io_close(fp, SM_TIME_DEFAULT); cleanup: errno = save_errno; return locked; } -/* +/* ** MCI_READ_PERSISTENT -- read persistent host status file ** ** Parameters: @@ -789,7 +853,7 @@ cleanup: static int mci_read_persistent(fp, mci) - FILE *fp; + SM_FILE_T *fp; register MCI *mci; { int ver; @@ -803,19 +867,17 @@ mci_read_persistent(fp, mci) syserr("mci_read_persistent: NULL mci"); if (tTd(56, 93)) { - dprintf("mci_read_persistent: fp=%lx, mci=", (u_long) fp); - mci_dump(mci, FALSE); + sm_dprintf("mci_read_persistent: fp=%lx, mci=", + (unsigned long) fp); } - mci->mci_status = NULL; - if (mci->mci_rstatus != NULL) - sm_free(mci->mci_rstatus); - mci->mci_rstatus = NULL; + SM_FREE_CLR(mci->mci_status); + SM_FREE_CLR(mci->mci_rstatus); - rewind(fp); + sm_io_rewind(fp, SM_TIME_DEFAULT); ver = -1; LineNumber = 0; - while (fgets(buf, sizeof buf, fp) != NULL) + while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf, sizeof buf) != NULL) { LineNumber++; p = strchr(buf, '\n'); @@ -855,6 +917,8 @@ mci_read_persistent(fp, mci) break; case '.': /* end of file */ + if (tTd(56, 93)) + mci_dump(mci, false); return 0; default: @@ -867,11 +931,13 @@ mci_read_persistent(fp, mci) } } LineNumber = saveLineNumber; + if (tTd(56, 93)) + sm_dprintf("incomplete (missing dot for EOF)\n"); if (ver < 0) return -1; return 0; } -/* +/* ** MCI_STORE_PERSISTENT -- Store persistent MCI information ** ** Store information about host that is kept @@ -893,7 +959,7 @@ mci_store_persistent(mci) if (mci == NULL) { if (tTd(56, 1)) - dprintf("mci_store_persistent: NULL mci\n"); + sm_dprintf("mci_store_persistent: NULL mci\n"); return; } @@ -901,40 +967,47 @@ mci_store_persistent(mci) return; if (tTd(56, 1)) - dprintf("mci_store_persistent: Storing information for %s\n", - mci->mci_host); + sm_dprintf("mci_store_persistent: Storing information for %s\n", + mci->mci_host); if (mci->mci_statfile == NULL) { if (tTd(56, 1)) - dprintf("mci_store_persistent: no statfile\n"); + sm_dprintf("mci_store_persistent: no statfile\n"); return; } - rewind(mci->mci_statfile); + sm_io_rewind(mci->mci_statfile, SM_TIME_DEFAULT); #if !NOFTRUNCATE - (void) ftruncate(fileno(mci->mci_statfile), (off_t) 0); + (void) ftruncate(sm_io_getinfo(mci->mci_statfile, SM_IO_WHAT_FD, NULL), + (off_t) 0); #endif /* !NOFTRUNCATE */ - fprintf(mci->mci_statfile, "V0\n"); - fprintf(mci->mci_statfile, "E%d\n", mci->mci_errno); - fprintf(mci->mci_statfile, "H%d\n", mci->mci_herrno); - fprintf(mci->mci_statfile, "S%d\n", mci->mci_exitstat); + (void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, "V0\n"); + (void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, "E%d\n", + mci->mci_errno); + (void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, "H%d\n", + mci->mci_herrno); + (void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, "S%d\n", + mci->mci_exitstat); if (mci->mci_status != NULL) - fprintf(mci->mci_statfile, "D%.80s\n", - denlstring(mci->mci_status, TRUE, FALSE)); + (void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, + "D%.80s\n", + denlstring(mci->mci_status, true, false)); if (mci->mci_rstatus != NULL) - fprintf(mci->mci_statfile, "R%.80s\n", - denlstring(mci->mci_rstatus, TRUE, FALSE)); - fprintf(mci->mci_statfile, "U%ld\n", (long)(mci->mci_lastuse)); - fprintf(mci->mci_statfile, ".\n"); + (void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, + "R%.80s\n", + denlstring(mci->mci_rstatus, true, false)); + (void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, "U%ld\n", + (long)(mci->mci_lastuse)); + (void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, ".\n"); - (void) fflush(mci->mci_statfile); + (void) sm_io_flush(mci->mci_statfile, SM_TIME_DEFAULT); errno = save_errno; return; } -/* +/* ** MCI_TRAVERSE_PERSISTENT -- walk persistent status tree ** ** Recursively find all the mci host files in `pathname'. Default to @@ -974,39 +1047,39 @@ mci_traverse_persistent(action, pathname) return -1; if (tTd(56, 1)) - dprintf("mci_traverse: pathname is %s\n", pathname); + sm_dprintf("mci_traverse: pathname is %s\n", pathname); ret = stat(pathname, &statbuf); if (ret < 0) { if (tTd(56, 2)) - dprintf("mci_traverse: Failed to stat %s: %s\n", - pathname, errstring(errno)); + sm_dprintf("mci_traverse: Failed to stat %s: %s\n", + pathname, sm_errstring(errno)); return ret; } if (S_ISDIR(statbuf.st_mode)) { - struct dirent *e; + bool leftone, removedone; + size_t len; char *newptr; + struct dirent *e; char newpath[MAXPATHLEN + 1]; - bool leftone, removedone; if ((d = opendir(pathname)) == NULL) { if (tTd(56, 2)) - dprintf("mci_traverse: opendir %s: %s\n", - pathname, errstring(errno)); + sm_dprintf("mci_traverse: opendir %s: %s\n", + pathname, sm_errstring(errno)); return -1; } - - if (strlen(pathname) >= sizeof newpath - MAXNAMLEN - 3) + len = sizeof(newpath) - MAXNAMLEN - 3; + if (sm_strlcpy(newpath, pathname, len) >= len) { if (tTd(56, 2)) - dprintf("mci_traverse: path \"%s\" too long", + sm_dprintf("mci_traverse: path \"%s\" too long", pathname); return -1; } - (void) strlcpy(newpath, pathname, sizeof newpath); newptr = newpath + strlen(newpath); *newptr++ = '/'; @@ -1016,15 +1089,16 @@ mci_traverse_persistent(action, pathname) ** during these loops, but it's better than doing ** a rewinddir() inside the inner loop */ + do { - leftone = removedone = FALSE; + leftone = removedone = false; while ((e = readdir(d)) != NULL) { if (e->d_name[0] == '.') continue; - (void) strlcpy(newptr, e->d_name, + (void) sm_strlcpy(newptr, e->d_name, sizeof newpath - (newptr - newpath)); @@ -1034,22 +1108,24 @@ mci_traverse_persistent(action, pathname) if (ret < 0) break; if (ret == 1) - leftone = TRUE; + leftone = true; if (!removedone && ret == 0 && action == mci_purge_persistent) - removedone = TRUE; + removedone = true; } if (ret < 0) break; + /* ** The following appears to be ** necessary during purges, since ** we modify the directory structure */ + if (removedone) rewinddir(d); if (tTd(56, 40)) - dprintf("mci_traverse: path %s: ret %d removed %d left %d\n", + sm_dprintf("mci_traverse: path %s: ret %d removed %d left %d\n", pathname, ret, removedone, leftone); } while (removedone); @@ -1097,12 +1173,13 @@ mci_traverse_persistent(action, pathname) ** Do something with the file containing the persistent ** information. */ + ret = (*action)(pathname, host); } return ret; } -/* +/* ** MCI_PRINT_PERSISTENT -- print persistent info ** ** Dump the persistent information in the file 'pathname' @@ -1120,8 +1197,8 @@ mci_print_persistent(pathname, hostname) char *pathname; char *hostname; { - static int initflag = FALSE; - FILE *fp; + static bool initflag = false; + SM_FILE_T *fp; int width = Verbose ? 78 : 25; bool locked; MCI mcib; @@ -1135,18 +1212,19 @@ mci_print_persistent(pathname, hostname) if (!initflag) { - initflag = TRUE; - printf(" -------------- Hostname --------------- How long ago ---------Results---------\n"); + initflag = true; + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " -------------- Hostname --------------- How long ago ---------Results---------\n"); } - fp = safefopen(pathname, O_RDWR, FileMode, + fp = safefopen(pathname, O_RDONLY, FileMode, SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY|SFF_SAFEDIRPATH); if (fp == NULL) { if (tTd(56, 1)) - dprintf("mci_print_persistent: cannot open %s: %s\n", - pathname, errstring(errno)); + sm_dprintf("mci_print_persistent: cannot open %s: %s\n", + pathname, sm_errstring(errno)); return 0; } @@ -1155,47 +1233,53 @@ mci_print_persistent(pathname, hostname) if (mci_read_persistent(fp, &mcib) < 0) { syserr("%s: could not read status file", pathname); - (void) fclose(fp); + (void) sm_io_close(fp, SM_TIME_DEFAULT); FileName = NULL; return 0; } - locked = !lockfile(fileno(fp), pathname, "", LOCK_EX|LOCK_NB); - (void) fclose(fp); + locked = !lockfile(sm_io_getinfo(fp, SM_IO_WHAT_FD, NULL), pathname, + "", LOCK_SH|LOCK_NB); + (void) sm_io_close(fp, SM_TIME_DEFAULT); FileName = NULL; - printf("%c%-39s %12s ", - locked ? '*' : ' ', hostname, - pintvl(curtime() - mcib.mci_lastuse, TRUE)); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%c%-39s %12s ", + locked ? '*' : ' ', hostname, + pintvl(curtime() - mcib.mci_lastuse, true)); if (mcib.mci_rstatus != NULL) - printf("%.*s\n", width, mcib.mci_rstatus); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%.*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)); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Deferred: %.*s\n", width - 10, + sm_errstring(mcib.mci_errno)); else if (mcib.mci_exitstat != 0) { - int i = mcib.mci_exitstat - EX__BASE; - extern int N_SysEx; - extern char *SysExMsg[]; + char *exmsg = sm_sysexmsg(mcib.mci_exitstat); - if (i < 0 || i >= N_SysEx) + if (exmsg == NULL) { char buf[80]; - snprintf(buf, sizeof buf, "Unknown mailer error %d", + (void) sm_snprintf(buf, sizeof buf, + "Unknown mailer error %d", mcib.mci_exitstat); - printf("%.*s\n", width, buf); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%.*s\n", + width, buf); } else - printf("%.*s\n", width, &(SysExMsg[i])[5]); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%.*s\n", + width, &exmsg[5]); } else if (mcib.mci_errno == 0) - printf("OK\n"); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "OK\n"); else - printf("OK: %.*s\n", width - 4, errstring(mcib.mci_errno)); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "OK: %.*s\n", + width - 4, sm_errstring(mcib.mci_errno)); return 0; } -/* +/* ** MCI_PURGE_PERSISTENT -- Remove a persistence status file. ** ** Parameters: @@ -1219,14 +1303,14 @@ mci_purge_persistent(pathname, hostname) int ret; if (tTd(56, 1)) - dprintf("mci_purge_persistent: purging %s\n", pathname); + sm_dprintf("mci_purge_persistent: purging %s\n", pathname); ret = stat(pathname, &statbuf); if (ret < 0) { if (tTd(56, 2)) - dprintf("mci_purge_persistent: Failed to stat %s: %s\n", - pathname, errstring(errno)); + sm_dprintf("mci_purge_persistent: Failed to stat %s: %s\n", + pathname, sm_errstring(errno)); return ret; } if (curtime() - statbuf.st_mtime < MciInfoTimeout) @@ -1234,11 +1318,17 @@ mci_purge_persistent(pathname, hostname) if (hostname != NULL) { /* remove the file */ - if (unlink(pathname) < 0) + ret = unlink(pathname); + if (ret < 0) { + if (LogLevel > 8) + sm_syslog(LOG_ERR, NOQID, + "mci_purge_persistent: failed to unlink %s: %s", + pathname, sm_errstring(errno)); if (tTd(56, 2)) - dprintf("mci_purge_persistent: failed to unlink %s: %s\n", - pathname, errstring(errno)); + sm_dprintf("mci_purge_persistent: failed to unlink %s: %s\n", + pathname, sm_errstring(errno)); + return ret; } } else @@ -1248,20 +1338,21 @@ mci_purge_persistent(pathname, hostname) return 1; if (tTd(56, 1)) - dprintf("mci_purge_persistent: dpurge %s\n", pathname); + sm_dprintf("mci_purge_persistent: dpurge %s\n", pathname); - if (rmdir(pathname) < 0) + ret = rmdir(pathname); + if (ret < 0) { if (tTd(56, 2)) - dprintf("mci_purge_persistent: rmdir %s: %s\n", - pathname, errstring(errno)); + sm_dprintf("mci_purge_persistent: rmdir %s: %s\n", + pathname, sm_errstring(errno)); + return ret; } - } return 0; } -/* +/* ** MCI_GENERATE_PERSISTENT_PATH -- generate path from hostname ** ** Given `host', convert from a.b.c to $QueueDir/.hoststat/c./b./a, @@ -1311,7 +1402,7 @@ mci_generate_persistent_path(host, path, pathlen, createflag) } if (tTd(56, 80)) - dprintf("mci_generate_persistent_path(%s): ", host); + sm_dprintf("mci_generate_persistent_path(%s): ", host); if (*host == '\0' || *host == '.') return -1; @@ -1320,9 +1411,9 @@ mci_generate_persistent_path(host, path, pathlen, createflag) if (strlen(host) > sizeof t_host - 1) return -1; if (host[0] == '[') - (void) strlcpy(t_host, host + 1, sizeof t_host); + (void) sm_strlcpy(t_host, host + 1, sizeof t_host); else - (void) strlcpy(t_host, host, sizeof t_host); + (void) sm_strlcpy(t_host, host, sizeof t_host); /* ** Delete any trailing dots from the hostname. @@ -1334,18 +1425,21 @@ mci_generate_persistent_path(host, path, pathlen, createflag) (elem[-1] == '.' || (host[0] == '[' && elem[-1] == ']'))) *--elem = '\0'; -#if NETINET || NETINET6 /* check for bogus bracketed address */ - if (host[0] == '[' + if (host[0] == '[') + { + bool good = false; # if NETINET6 - && inet_pton(AF_INET6, t_host, &in6_addr) != 1 + if (anynet_pton(AF_INET6, t_host, &in6_addr) == 1) + good = true; # endif /* NETINET6 */ # if NETINET - && inet_addr(t_host) == INADDR_NONE + if (inet_addr(t_host) != INADDR_NONE) + good = true; # endif /* NETINET */ - ) - return -1; -#endif /* NETINET || NETINET6 */ + if (!good) + return -1; + } /* check for what will be the final length of the path */ len = strlen(HostStatDir) + 2; @@ -1359,10 +1453,8 @@ mci_generate_persistent_path(host, path, pathlen, createflag) } if (len > pathlen || len < 1) return -1; - - (void) strlcpy(path, HostStatDir, pathlen); + (void) sm_strlcpy(path, HostStatDir, pathlen); p = path + strlen(path); - while (elem > t_host) { if (!path_is_dir(path, createflag)) @@ -1387,14 +1479,12 @@ mci_generate_persistent_path(host, path, pathlen, createflag) *p++ = '.'; *p = '\0'; } - if (tTd(56, 80)) { if (ret < 0) - dprintf("FAILURE %d\n", ret); + sm_dprintf("FAILURE %d\n", ret); else - dprintf("SUCCESS %s\n", path); + sm_dprintf("SUCCESS %s\n", path); } - return ret; } diff --git a/contrib/sendmail/src/savemail.c b/contrib/sendmail/src/savemail.c index 4e310ba..0324591 100644 --- a/contrib/sendmail/src/savemail.c +++ b/contrib/sendmail/src/savemail.c @@ -11,14 +11,11 @@ * */ -#ifndef lint -static char id[] = "@(#)$Id: savemail.c,v 8.212.4.13 2001/05/03 17:24:15 gshapiro Exp $"; -#endif /* ! lint */ - /* $FreeBSD$ */ #include <sendmail.h> +SM_RCSID("@(#)$Id: savemail.c,v 8.297 2001/12/28 22:32:19 ca Exp $") static void errbody __P((MCI *, ENVELOPE *, char *)); static bool pruneroute __P((char *)); @@ -33,11 +30,12 @@ static bool pruneroute __P((char *)); ** ** Parameters: ** e -- the envelope containing the message in error. -** sendbody -- if TRUE, also send back the body of the +** sendbody -- if true, also send back the body of the ** message; otherwise just send the header. ** ** Returns: -** none +** true if savemail panic'ed, (i.e., the data file should +** be preserved by dropenvelope()) ** ** Side Effects: ** Saves the letter, by writing or mailing it back to the @@ -55,14 +53,13 @@ static bool pruneroute __P((char *)); #define ESM_PANIC 6 /* call loseqfile() */ #define ESM_DONE 7 /* message is successfully delivered */ - -void +bool savemail(e, sendbody) register ENVELOPE *e; bool sendbody; { - register struct passwd *pw; - register FILE *fp; + register SM_FILE_T *fp; + bool panic = false; int state; auto ADDRESS *q = NULL; register char *p; @@ -70,19 +67,21 @@ savemail(e, sendbody) int flags; long sff; char buf[MAXLINE + 1]; + SM_MBDB_T user; + if (tTd(6, 1)) { - dprintf("\nsavemail, errormode = %c, id = %s, ExitStat = %d\n e_from=", + sm_dprintf("\nsavemail, errormode = %c, id = %s, ExitStat = %d\n e_from=", e->e_errormode, e->e_id == NULL ? "NONE" : e->e_id, ExitStat); - printaddr(&e->e_from, FALSE); + printaddr(&e->e_from, false); } if (e->e_id == NULL) { /* can't return a message with no id */ - return; + return panic; } /* @@ -94,10 +93,11 @@ savemail(e, sendbody) { e->e_sender = "Postmaster"; if (parseaddr(e->e_sender, &e->e_from, - RF_COPYPARSE|RF_SENDERADDR, '\0', NULL, e) == NULL) + RF_COPYPARSE|RF_SENDERADDR, + '\0', NULL, e, false) == NULL) { syserr("553 5.3.5 Cannot parse Postmaster!"); - finis(TRUE, EX_SOFTWARE); + finis(true, true, EX_SOFTWARE); } } e->e_to = NULL; @@ -137,10 +137,10 @@ savemail(e, sendbody) case EM_QUIET: /* no need to return anything at all */ - return; + return panic; default: - syserr("554 5.3.0 savemail: bogus errormode x%x\n", + syserr("554 5.3.0 savemail: bogus errormode x%x", e->e_errormode); state = ESM_MAIL; break; @@ -153,7 +153,7 @@ savemail(e, sendbody) bitset(EF_RESPONSE, e->e_parent->e_flags)) { /* got an error sending a response -- can it */ - return; + return panic; } state = ESM_POSTMASTER; } @@ -161,7 +161,7 @@ savemail(e, sendbody) while (state != ESM_DONE) { if (tTd(6, 5)) - dprintf(" state %d\n", state); + sm_dprintf(" state %d\n", state); switch (state) { @@ -180,29 +180,41 @@ savemail(e, sendbody) */ p = ttypath(); - if (p == NULL || freopen(p, "w", stdout) == NULL) + if (p == NULL || sm_io_reopen(SmFtStdio, + SM_TIME_DEFAULT, + p, SM_IO_WRONLY, NULL, + smioout) == NULL) { state = ESM_MAIL; break; } expand("\201n", buf, sizeof buf, e); - printf("\r\nMessage from %s...\r\n", buf); - printf("Errors occurred while sending mail.\r\n"); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "\r\nMessage from %s...\r\n", buf); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Errors occurred while sending mail.\r\n"); if (e->e_xfp != NULL) { (void) bfrewind(e->e_xfp); - printf("Transcript follows:\r\n"); - while (fgets(buf, sizeof buf, e->e_xfp) != NULL && - !ferror(stdout)) - (void) fputs(buf, stdout); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Transcript follows:\r\n"); + while (sm_io_fgets(e->e_xfp, SM_TIME_DEFAULT, + buf, sizeof buf) != NULL && + !sm_io_error(smioout)) + (void) sm_io_fputs(smioout, + SM_TIME_DEFAULT, + buf); } else { - syserr("Cannot open %s", queuename(e, 'x')); - printf("Transcript of session is unavailable.\r\n"); + syserr("Cannot open %s", + queuename(e, XSCRPT_LETTER)); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Transcript of session is unavailable.\r\n"); } - printf("Original message will be saved in dead.letter.\r\n"); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Original message will be saved in dead.letter.\r\n"); state = ESM_DEADLETTER; break; @@ -227,32 +239,23 @@ savemail(e, sendbody) if (ExitStat == EX_CONFIG || ExitStat == EX_SOFTWARE) { - (void) sendtolist("postmaster", - NULLADDR, &e->e_errorqueue, 0, e); + (void) sendtolist("postmaster", NULLADDR, + &e->e_errorqueue, 0, e); } if (!emptyaddr(&e->e_from)) { char from[TOBUFSIZE]; - if (strlen(e->e_from.q_paddr) >= sizeof from) + if (sm_strlcpy(from, e->e_from.q_paddr, + sizeof from) >= sizeof from) { state = ESM_POSTMASTER; break; } - (void) strlcpy(from, e->e_from.q_paddr, - sizeof from); - if (!DontPruneRoutes && pruneroute(from)) - { - ADDRESS *a; - - for (a = e->e_errorqueue; a != NULL; - a = a->q_next) - { - if (sameaddr(a, &e->e_from)) - a->q_state = QS_DUPLICATE; - } - } + if (!DontPruneRoutes) + (void) pruneroute(from); + (void) sendtolist(from, NULLADDR, &e->e_errorqueue, 0, e); } @@ -299,6 +302,17 @@ savemail(e, sendbody) q = NULL; expand(DoubleBounceAddr, buf, sizeof buf, e); + + /* + ** Just drop it on the floor if DoubleBounceAddr + ** expands to an empty string. + */ + + if (*buf == '\0') + { + state = ESM_DONE; + break; + } if (sendtolist(buf, NULLADDR, &q, 0, e) <= 0) { syserr("553 5.3.0 cannot parse %s!", buf); @@ -334,9 +348,10 @@ savemail(e, sendbody) { if (e->e_from.q_home != NULL) p = e->e_from.q_home; - else if ((pw = sm_getpwnam(e->e_from.q_user)) != NULL && - *pw->pw_dir != '\0') - p = pw->pw_dir; + else if (sm_mbdb_lookup(e->e_from.q_user, &user) + == EX_OK && + *user.mbdb_homedir != '\0') + p = user.mbdb_homedir; } if (p == NULL || e->e_dfp == NULL) { @@ -346,11 +361,11 @@ savemail(e, sendbody) } /* we have a home directory; write dead.letter */ - define('z', p, e); + macdefine(&e->e_macro, A_TEMP, 'z', p); /* get the sender for the UnixFromLine */ p = macvalue('g', e); - define('g', e->e_sender, e); + macdefine(&e->e_macro, A_PERM, 'g', e->e_sender); expand("\201z/dead.letter", buf, sizeof buf, e); sff = SFF_CREAT|SFF_REGONLY|SFF_RUNASREALUID; @@ -367,11 +382,11 @@ savemail(e, sendbody) if (Verbose > 0) message("Saved message in %s", buf); Verbose = oldverb; - define('g', p, e); + macdefine(&e->e_macro, A_PERM, 'g', p); state = ESM_DONE; break; } - define('g', p, e); + macdefine(&e->e_macro, A_PERM, 'g', p); state = ESM_MAIL; break; @@ -411,15 +426,15 @@ savemail(e, sendbody) /* get the sender for the UnixFromLine */ p = macvalue('g', e); - define('g', e->e_sender, e); + macdefine(&e->e_macro, A_PERM, 'g', e->e_sender); putfromline(&mcibuf, e); (*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER); (*e->e_putbody)(&mcibuf, e, NULL); - putline("\n", &mcibuf); - (void) fflush(fp); - if (ferror(fp) || - fclose(fp) < 0) + putline("\n", &mcibuf); /* XXX EOL from FileMailer? */ + (void) sm_io_flush(fp, SM_TIME_DEFAULT); + if (sm_io_error(fp) || + sm_io_close(fp, SM_TIME_DEFAULT) < 0) state = ESM_PANIC; else { @@ -437,23 +452,26 @@ savemail(e, sendbody) DeadLetterDrop); state = ESM_DONE; } - define('g', p, e); + macdefine(&e->e_macro, A_PERM, 'g', p); break; default: syserr("554 5.3.5 savemail: unknown state %d", state); - /* FALLTHROUGH */ case ESM_PANIC: /* leave the locked queue & transcript files around */ loseqfile(e, "savemail panic"); + panic = true; errno = 0; - syserr("!554 savemail: cannot save rejected email anywhere"); + syserr("554 savemail: cannot save rejected email anywhere"); + state = ESM_DONE; + break; } } + return panic; } -/* +/* ** RETURNTOSENDER -- return a message to the sender with an error. ** ** Parameters: @@ -470,12 +488,11 @@ savemail(e, sendbody) ** else -- some error. ** ** Side Effects: -** Returns the current message to the sender via -** mail. +** Returns the current message to the sender via mail. */ #define MAXRETURNS 6 /* max depth of returning messages */ -#define ERRORFUDGE 100 /* nominal size of error message text */ +#define ERRORFUDGE 1024 /* nominal size of error message text */ int returntosender(msg, returnq, flags, e) @@ -500,13 +517,13 @@ returntosender(msg, returnq, flags, e) if (tTd(6, 1)) { - dprintf("\n*** Return To Sender: msg=\"%s\", depth=%d, e=%lx, returnq=", - msg, returndepth, (u_long) e); - printaddr(returnq, TRUE); + sm_dprintf("\n*** Return To Sender: msg=\"%s\", depth=%d, e=%p, returnq=", + msg, returndepth, e); + printaddr(returnq, true); if (tTd(6, 20)) { - dprintf("Sendq="); - printaddr(e->e_sendqueue, TRUE); + sm_dprintf("Sendq="); + printaddr(e->e_sendqueue, true); } } @@ -520,32 +537,32 @@ returntosender(msg, returnq, flags, e) return 0; } - define('g', e->e_sender, e); - define('u', NULL, e); + macdefine(&e->e_macro, A_PERM, 'g', e->e_sender); + macdefine(&e->e_macro, A_PERM, 'u', NULL); /* initialize error envelope */ - ee = newenvelope(&errenvelope, e); - define('a', "\201b", ee); - define('r', "", ee); - define('s', "localhost", ee); - define('_', "localhost", ee); + ee = newenvelope(&errenvelope, e, sm_rpool_new_x(NULL)); + macdefine(&ee->e_macro, A_PERM, 'a', "\201b"); + macdefine(&ee->e_macro, A_PERM, 'r', ""); + macdefine(&ee->e_macro, A_PERM, 's', "localhost"); + macdefine(&ee->e_macro, A_PERM, '_', "localhost"); #if SASL - define(macid("{auth_type}", NULL), "", ee); - define(macid("{auth_authen}", NULL), "", ee); - define(macid("{auth_author}", NULL), "", ee); - define(macid("{auth_ssf}", NULL), "", ee); + macdefine(&ee->e_macro, A_PERM, macid("{auth_type}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{auth_authen}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{auth_author}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{auth_ssf}"), ""); #endif /* SASL */ #if STARTTLS - define(macid("{cert_issuer}", NULL), "", ee); - define(macid("{cert_subject}", NULL), "", ee); - define(macid("{cipher_bits}", NULL), "", ee); - define(macid("{cipher}", NULL), "", ee); - define(macid("{tls_version}", NULL), "", ee); - define(macid("{verify}", NULL), "", ee); + macdefine(&ee->e_macro, A_PERM, macid("{cert_issuer}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{cert_subject}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{cipher_bits}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{cipher}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{tls_version}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{verify}"), ""); # if _FFR_TLS_1 - define(macid("{alg_bits}", NULL), "", ee); - define(macid("{cn_issuer}", NULL), "", ee); - define(macid("{cn_subject}", NULL), "", ee); + macdefine(&ee->e_macro, A_PERM, macid("{alg_bits}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{cn_issuer}"), ""); + macdefine(&ee->e_macro, A_PERM, macid("{cn_subject}"), ""); # endif /* _FFR_TLS_1 */ #endif /* STARTTLS */ @@ -569,12 +586,21 @@ returntosender(msg, returnq, flags, e) } ee->e_sendqueue = returnq; - ee->e_msgsize = ERRORFUDGE; + ee->e_msgsize = 0; if (bitset(RTSF_SEND_BODY, flags) && !bitset(PRIV_NOBODYRETN, PrivacyFlags)) - ee->e_msgsize += e->e_msgsize; + ee->e_msgsize = ERRORFUDGE + e->e_msgsize; else ee->e_flags |= EF_NO_BODY_RETN; + + if (!setnewqueue(ee)) + { + syserr("554 5.3.0 returntosender: cannot select queue for %s", + returnq->q_paddr); + ExitStat = EX_UNAVAILABLE; + returndepth--; + return -1; + } initsys(ee); #if NAMED_BIND @@ -593,7 +619,7 @@ returntosender(msg, returnq, flags, e) ee->e_nrcpts++; if (q->q_alias == NULL) - addheader("To", q->q_paddr, 0, &ee->e_header); + addheader("To", q->q_paddr, 0, ee); } if (LogLevel > 5) @@ -606,72 +632,69 @@ returntosender(msg, returnq, flags, e) p = "postmaster notify"; else p = "DSN"; - sm_syslog(LOG_INFO, e->e_id, - "%s: %s: %s", + sm_syslog(LOG_INFO, e->e_id, "%s: %s: %s", ee->e_id, p, shortenstring(msg, MAXSHORTSTR)); } if (SendMIMEErrors) { - addheader("MIME-Version", "1.0", 0, &ee->e_header); - - (void) snprintf(buf, sizeof buf, "%s.%ld/%.100s", - ee->e_id, (long) curtime(), MyHostName); - ee->e_msgboundary = newstr(buf); - (void) snprintf(buf, sizeof buf, + addheader("MIME-Version", "1.0", 0, ee); + (void) sm_snprintf(buf, sizeof buf, "%s.%ld/%.100s", + ee->e_id, (long)curtime(), MyHostName); + ee->e_msgboundary = sm_rpool_strdup_x(ee->e_rpool, buf); + (void) sm_snprintf(buf, sizeof buf, #if DSN "multipart/report; report-type=delivery-status;\n\tboundary=\"%s\"", #else /* DSN */ "multipart/mixed; boundary=\"%s\"", #endif /* DSN */ ee->e_msgboundary); - addheader("Content-Type", buf, 0, &ee->e_header); + addheader("Content-Type", buf, 0, ee); p = hvalue("Content-Transfer-Encoding", e->e_header); - if (p != NULL && strcasecmp(p, "binary") != 0) + if (p != NULL && sm_strcasecmp(p, "binary") != 0) p = NULL; if (p == NULL && bitset(EF_HAS8BIT, e->e_flags)) p = "8bit"; if (p != NULL) - addheader("Content-Transfer-Encoding", - p, 0, &ee->e_header); + addheader("Content-Transfer-Encoding", p, 0, ee); } if (strncmp(msg, "Warning:", 8) == 0) { - addheader("Subject", msg, 0, &ee->e_header); + addheader("Subject", msg, 0, ee); p = "warning-timeout"; } else if (strncmp(msg, "Postmaster warning:", 19) == 0) { - addheader("Subject", msg, 0, &ee->e_header); + addheader("Subject", msg, 0, ee); p = "postmaster-warning"; } else if (strcmp(msg, "Return receipt") == 0) { - addheader("Subject", msg, 0, &ee->e_header); + addheader("Subject", msg, 0, ee); p = "return-receipt"; } else if (bitset(RTSF_PM_BOUNCE, flags)) { - snprintf(buf, sizeof buf, + (void) sm_snprintf(buf, sizeof buf, "Postmaster notify: see transcript for details"); - addheader("Subject", buf, 0, &ee->e_header); + addheader("Subject", buf, 0, ee); p = "postmaster-notification"; } else { - snprintf(buf, sizeof buf, + (void) sm_snprintf(buf, sizeof buf, "Returned mail: see transcript for details"); - addheader("Subject", buf, 0, &ee->e_header); + addheader("Subject", buf, 0, ee); p = "failure"; } - (void) snprintf(buf, sizeof buf, "auto-generated (%s)", p); - addheader("Auto-Submitted", buf, 0, &ee->e_header); + (void) sm_snprintf(buf, sizeof buf, "auto-generated (%s)", p); + addheader("Auto-Submitted", buf, 0, ee); /* fake up an address header for the from person */ expand("\201n", buf, sizeof buf, e); if (parseaddr(buf, &ee->e_from, - RF_COPYALL|RF_SENDERADDR, '\0', NULL, e) == NULL) + RF_COPYALL|RF_SENDERADDR, '\0', NULL, e, false) == NULL) { syserr("553 5.3.5 Can't parse myself!"); ExitStat = EX_SOFTWARE; @@ -684,18 +707,19 @@ returntosender(msg, returnq, flags, e) /* push state into submessage */ CurEnv = ee; - define('f', "\201n", ee); - define('x', "Mail Delivery Subsystem", ee); - eatheader(ee, TRUE); + macdefine(&ee->e_macro, A_PERM, 'f', "\201n"); + macdefine(&ee->e_macro, A_PERM, 'x', "Mail Delivery Subsystem"); + eatheader(ee, true, true); /* mark statistics */ - markstats(ee, NULLADDR, FALSE); + markstats(ee, NULLADDR, STATS_NORMAL); /* actually deliver the error message */ sendall(ee, SM_DELIVER); /* restore state */ - dropenvelope(ee, TRUE); + dropenvelope(ee, true, false); + sm_rpool_free(ee->e_rpool); CurEnv = oldcur; returndepth--; @@ -710,7 +734,7 @@ returntosender(msg, returnq, flags, e) } return -1; } -/* +/* ** ERRBODY -- output the body of an error message. ** ** Typically this is a copy of the transcript plus a copy of the @@ -719,7 +743,7 @@ returntosender(msg, returnq, flags, e) ** Parameters: ** mci -- the mailer connection information. ** e -- the envelope we are working in. -** separator -- any possible MIME separator. +** separator -- any possible MIME separator (unused). ** ** Returns: ** none @@ -739,9 +763,10 @@ errbody(mci, e, separator) bool sendbody; bool pm_notify; int save_errno; - register FILE *xfile; + register SM_FILE_T *xfile; char *p; register ADDRESS *q = NULL; + char actual[MAXLINE]; char buf[MAXLINE]; if (bitset(MCIF_INHEADER, mci->mci_flags)) @@ -764,7 +789,7 @@ errbody(mci, e, separator) { putline("This is a MIME-encapsulated message", mci); putline("", mci); - (void) snprintf(buf, sizeof buf, "--%s", e->e_msgboundary); + (void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary); putline(buf, mci); putline("", mci); } @@ -773,10 +798,10 @@ errbody(mci, e, separator) ** Output introductory information. */ - pm_notify = FALSE; + pm_notify = false; p = hvalue("subject", e->e_header); if (p != NULL && strncmp(p, "Postmaster ", 11) == 0) - pm_notify = TRUE; + pm_notify = true; else { for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) @@ -798,8 +823,9 @@ errbody(mci, e, separator) mci); putline("", mci); } - snprintf(buf, sizeof buf, "The original message was received at %s", - arpadate(ctime(&e->e_parent->e_ctime))); + (void) sm_snprintf(buf, sizeof buf, + "The original message was received at %s", + arpadate(ctime(&e->e_parent->e_ctime))); putline(buf, mci); expand("from \201_", buf, sizeof buf, e->e_parent); putline(buf, mci); @@ -807,7 +833,8 @@ errbody(mci, e, separator) /* include id in postmaster copies */ if (pm_notify && e->e_parent->e_id != NULL) { - snprintf(buf, sizeof buf, "with id %s", e->e_parent->e_id); + (void) sm_strlcpyn(buf, sizeof buf, 2, "with id ", + e->e_parent->e_id); putline(buf, mci); } putline("", mci); @@ -831,13 +858,14 @@ errbody(mci, e, separator) xfile = safefopen(ErrMsgFile, O_RDONLY, 0444, sff); if (xfile != NULL) { - while (fgets(buf, sizeof buf, xfile) != NULL) + while (sm_io_fgets(xfile, SM_TIME_DEFAULT, buf, + sizeof buf) != NULL) { translate_dollars(buf); expand(buf, buf, sizeof buf, e); putline(buf, mci); } - (void) fclose(xfile); + (void) sm_io_close(xfile, SM_TIME_DEFAULT); putline("\n", mci); } } @@ -853,7 +881,8 @@ errbody(mci, e, separator) ** Output message introduction */ - printheader = TRUE; + /* permanent fatal errors */ + printheader = true; for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) { if (!QS_IS_BADADDR(q->q_state) || @@ -864,35 +893,39 @@ errbody(mci, e, separator) { putline(" ----- The following addresses had permanent fatal errors -----", mci); - printheader = FALSE; + printheader = false; } - snprintf(buf, sizeof buf, "%s", - shortenstring(q->q_paddr, MAXSHORTSTR)); + (void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR), + sizeof buf); putline(buf, mci); if (q->q_rstatus != NULL) { - snprintf(buf, sizeof buf, " (reason: %s)", - shortenstring(exitstat(q->q_rstatus), - MAXSHORTSTR)); + (void) sm_snprintf(buf, sizeof buf, + " (reason: %s)", + shortenstring(exitstat(q->q_rstatus), + MAXSHORTSTR)); putline(buf, mci); } if (q->q_alias != NULL) { - snprintf(buf, sizeof buf, " (expanded from: %s)", - shortenstring(q->q_alias->q_paddr, - MAXSHORTSTR)); + (void) sm_snprintf(buf, sizeof buf, + " (expanded from: %s)", + shortenstring(q->q_alias->q_paddr, + MAXSHORTSTR)); putline(buf, mci); } } if (!printheader) putline("", mci); - printheader = TRUE; + /* transient non-fatal errors */ + printheader = true; for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) { if (QS_IS_BADADDR(q->q_state) || !bitset(QPRIMARY, q->q_flags) || + !bitset(QBYNDELAY, q->q_flags) || !bitset(QDELAYED, q->q_flags)) continue; @@ -900,30 +933,37 @@ errbody(mci, e, separator) { putline(" ----- The following addresses had transient non-fatal errors -----", mci); - printheader = FALSE; + printheader = false; } - snprintf(buf, sizeof buf, "%s", - shortenstring(q->q_paddr, MAXSHORTSTR)); + (void) sm_strlcpy(buf, shortenstring(q->q_paddr, MAXSHORTSTR), + sizeof buf); putline(buf, mci); if (q->q_alias != NULL) { - snprintf(buf, sizeof buf, " (expanded from: %s)", - shortenstring(q->q_alias->q_paddr, - MAXSHORTSTR)); + (void) sm_snprintf(buf, sizeof buf, + " (expanded from: %s)", + shortenstring(q->q_alias->q_paddr, + MAXSHORTSTR)); putline(buf, mci); } } if (!printheader) putline("", mci); - printheader = TRUE; + /* successful delivery notifications */ + printheader = true; for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) { if (QS_IS_BADADDR(q->q_state) || !bitset(QPRIMARY, q->q_flags) || + bitset(QBYNDELAY, q->q_flags) || bitset(QDELAYED, q->q_flags)) continue; + else if (bitset(QBYNRELAY, q->q_flags)) + p = "Deliver-By notify: relayed"; + else if (bitset(QBYTRACE, q->q_flags)) + p = "Deliver-By trace: relayed"; else if (!bitset(QPINGONSUCCESS, q->q_flags)) continue; else if (bitset(QRELAYED, q->q_flags)) @@ -944,17 +984,18 @@ errbody(mci, e, separator) { putline(" ----- The following addresses had successful delivery notifications -----", mci); - printheader = FALSE; + printheader = false; } - snprintf(buf, sizeof buf, "%s (%s)", + (void) sm_snprintf(buf, sizeof buf, "%s (%s)", shortenstring(q->q_paddr, MAXSHORTSTR), p); putline(buf, mci); if (q->q_alias != NULL) { - snprintf(buf, sizeof buf, " (expanded from: %s)", - shortenstring(q->q_alias->q_paddr, - MAXSHORTSTR)); + (void) sm_snprintf(buf, sizeof buf, + " (expanded from: %s)", + shortenstring(q->q_alias->q_paddr, + MAXSHORTSTR)); putline(buf, mci); } } @@ -965,7 +1006,7 @@ errbody(mci, e, separator) ** Output transcript of errors */ - (void) fflush(stdout); + (void) sm_io_flush(smioout, SM_TIME_DEFAULT); if (e->e_parent->e_xfp == NULL) { putline(" ----- Transcript of session is unavailable -----\n", @@ -973,16 +1014,17 @@ errbody(mci, e, separator) } else { - printheader = TRUE; + printheader = true; (void) bfrewind(e->e_parent->e_xfp); if (e->e_xfp != NULL) - (void) fflush(e->e_xfp); - while (fgets(buf, sizeof buf, e->e_parent->e_xfp) != NULL) + (void) sm_io_flush(e->e_xfp, SM_TIME_DEFAULT); + while (sm_io_fgets(e->e_parent->e_xfp, SM_TIME_DEFAULT, buf, + sizeof buf) != NULL) { if (printheader) putline(" ----- Transcript of session follows -----\n", mci); - printheader = FALSE; + printheader = false; putline(buf, mci); } } @@ -995,10 +1037,8 @@ errbody(mci, e, separator) if (e->e_msgboundary != NULL) { - time_t now = curtime(); - putline("", mci); - (void) snprintf(buf, sizeof buf, "--%s", e->e_msgboundary); + (void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary); putline(buf, mci); putline("Content-Type: message/delivery-status", mci); putline("", mci); @@ -1010,15 +1050,15 @@ errbody(mci, e, separator) /* original envelope id from MAIL FROM: line */ if (e->e_parent->e_envid != NULL) { - (void) snprintf(buf, sizeof buf, + (void) sm_snprintf(buf, sizeof buf, "Original-Envelope-Id: %.800s", xuntextify(e->e_parent->e_envid)); putline(buf, mci); } /* Reporting-MTA: is us (required) */ - (void) snprintf(buf, sizeof buf, "Reporting-MTA: dns; %.800s", - MyHostName); + (void) sm_snprintf(buf, sizeof buf, + "Reporting-MTA: dns; %.800s", MyHostName); putline(buf, mci); /* DSN-Gateway: not relevant since we are not translating */ @@ -1030,24 +1070,35 @@ errbody(mci, e, separator) if (e->e_parent->e_from.q_mailer == NULL || (p = e->e_parent->e_from.q_mailer->m_mtatype) == NULL) p = "dns"; - (void) snprintf(buf, sizeof buf, + (void) sm_snprintf(buf, sizeof buf, "Received-From-MTA: %s; %.800s", p, RealHostName); putline(buf, mci); } /* Arrival-Date: -- when it arrived here */ - (void) snprintf(buf, sizeof buf, "Arrival-Date: %s", + (void) sm_strlcpyn(buf, sizeof buf, 2, "Arrival-Date: ", arpadate(ctime(&e->e_parent->e_ctime))); putline(buf, mci); + /* Deliver-By-Date: -- when it should have been delivered */ + if (IS_DLVR_BY(e->e_parent)) + { + time_t dbyd; + + dbyd = e->e_parent->e_ctime + e->e_parent->e_deliver_by; + (void) sm_strlcpyn(buf, sizeof buf, 2, + "Deliver-By-Date: ", + arpadate(ctime(&dbyd))); + putline(buf, mci); + } + /* ** Output per-address information. */ for (q = e->e_parent->e_sendqueue; q != NULL; q = q->q_next) { - register ADDRESS *r; char *action; if (QS_IS_BADADDR(q->q_state)) @@ -1073,6 +1124,12 @@ errbody(mci, e, separator) action = "expanded (to multi-recipient alias)"; else if (bitset(QDELAYED, q->q_flags)) action = "delayed"; + else if (bitset(QBYTRACE, q->q_flags)) + action = "relayed (Deliver-By trace mode)"; + else if (bitset(QBYNDELAY, q->q_flags)) + action = "delayed (Deliver-By notify mode)"; + else if (bitset(QBYNRELAY, q->q_flags)) + action = "relayed (Deliver-By notify mode)"; else continue; @@ -1081,63 +1138,15 @@ errbody(mci, e, separator) /* Original-Recipient: -- passed from on high */ if (q->q_orcpt != NULL) { - (void) snprintf(buf, sizeof buf, + (void) sm_snprintf(buf, sizeof buf, "Original-Recipient: %.800s", q->q_orcpt); putline(buf, mci); } - /* Final-Recipient: -- the name from the RCPT command */ - p = e->e_parent->e_from.q_mailer->m_addrtype; - if (p == NULL) - p = "rfc822"; - for (r = q; r->q_alias != NULL; r = r->q_alias) - continue; - if (strcasecmp(p, "rfc822") != 0) - { - (void) snprintf(buf, sizeof buf, - "Final-Recipient: %s; %.800s", - r->q_mailer->m_addrtype, - r->q_user); - } - else if (strchr(r->q_user, '@') != NULL) - { - (void) snprintf(buf, sizeof buf, - "Final-Recipient: %s; %.800s", - p, r->q_user); - } - else if (strchr(r->q_paddr, '@') != NULL) - { - char *qp; - bool b; - - qp = r->q_paddr; - /* strip brackets from address */ - b = FALSE; - if (*qp == '<') - { - b = qp[strlen(qp) - 1] == '>'; - if (b) - qp[strlen(qp) - 1] = '\0'; - qp++; - } - (void) snprintf(buf, sizeof buf, - "Final-Recipient: %s; %.800s", - p, qp); - /* undo damage */ - if (b) - qp[strlen(qp)] = '>'; - } - else - { - (void) snprintf(buf, sizeof buf, - "Final-Recipient: %s; %.700s@%.100s", - p, r->q_user, MyHostName); - } - putline(buf, mci); - - /* X-Actual-Recipient: -- the real problem address */ - if (r != q && q->q_user[0] != '\0') + /* Figure out actual recipient */ + actual[0] = '\0'; + if (q->q_user[0] != '\0') { if (q->q_mailer != NULL && q->q_mailer->m_addrtype != NULL) @@ -1145,25 +1154,59 @@ errbody(mci, e, separator) else p = "rfc822"; - if (strcasecmp(p, "rfc822") == 0 && + if (sm_strcasecmp(p, "rfc822") == 0 && strchr(q->q_user, '@') == NULL) { - (void) snprintf(buf, sizeof buf, - "X-Actual-Recipient: %s; %.700s@%.100s", - p, q->q_user, - MyHostName); + (void) sm_snprintf(actual, + sizeof actual, + "%s; %.700s@%.100s", + p, q->q_user, + MyHostName); } else { - (void) snprintf(buf, sizeof buf, - "X-Actual-Recipient: %s; %.800s", - p, q->q_user); + (void) sm_snprintf(actual, + sizeof actual, + "%s; %.800s", + p, q->q_user); } + } + + /* Final-Recipient: -- the name from the RCPT command */ + if (q->q_finalrcpt == NULL) + { + /* should never happen */ + sm_syslog(LOG_ERR, e->e_id, + "returntosender: q_finalrcpt is NULL"); + + /* try to fall back to the actual recipient */ + if (actual[0] != '\0') + q->q_finalrcpt = sm_rpool_strdup_x(e->e_rpool, + actual); + } + + if (q->q_finalrcpt != NULL) + { + (void) sm_snprintf(buf, sizeof buf, + "Final-Recipient: %s", + q->q_finalrcpt); + putline(buf, mci); + } + + /* X-Actual-Recipient: -- the real problem address */ + if (actual[0] != '\0' && + q->q_finalrcpt != NULL && + strcmp(actual, q->q_finalrcpt) != 0) + { + (void) sm_snprintf(buf, sizeof buf, + "X-Actual-Recipient: %s", + actual); putline(buf, mci); } /* Action: -- what happened? */ - snprintf(buf, sizeof buf, "Action: %s", action); + (void) sm_strlcpyn(buf, sizeof buf, 2, "Action: ", + action); putline(buf, mci); /* Status: -- what _really_ happened? */ @@ -1175,7 +1218,7 @@ errbody(mci, e, separator) p = "4.0.0"; else p = "2.0.0"; - snprintf(buf, sizeof buf, "Status: %s", p); + (void) sm_strlcpyn(buf, sizeof buf, 2, "Status: ", p); putline(buf, mci); /* Remote-MTA: -- who was I talking to? */ @@ -1184,7 +1227,7 @@ errbody(mci, e, separator) if (q->q_mailer == NULL || (p = q->q_mailer->m_mtatype) == NULL) p = "dns"; - (void) snprintf(buf, sizeof buf, + (void) sm_snprintf(buf, sizeof buf, "Remote-MTA: %s; %.800s", p, q->q_statmta); p = &buf[strlen(buf) - 1]; @@ -1199,7 +1242,7 @@ errbody(mci, e, separator) p = q->q_mailer->m_diagtype; if (p == NULL) p = "smtp"; - (void) snprintf(buf, sizeof buf, + (void) sm_snprintf(buf, sizeof buf, "Diagnostic-Code: %s; %.800s", p, q->q_rstatus); putline(buf, mci); @@ -1207,9 +1250,9 @@ errbody(mci, e, separator) /* Last-Attempt-Date: -- fine granularity */ if (q->q_statdate == (time_t) 0L) - q->q_statdate = now; - (void) snprintf(buf, sizeof buf, - "Last-Attempt-Date: %s", + q->q_statdate = curtime(); + (void) sm_strlcpyn(buf, sizeof buf, 2, + "Last-Attempt-Date: ", arpadate(ctime(&q->q_statdate))); putline(buf, mci); @@ -1220,8 +1263,8 @@ errbody(mci, e, separator) xdate = e->e_parent->e_ctime + TimeOuts.to_q_return[e->e_parent->e_timeoutclass]; - snprintf(buf, sizeof buf, - "Will-Retry-Until: %s", + (void) sm_strlcpyn(buf, sizeof buf, 2, + "Will-Retry-Until: ", arpadate(ctime(&xdate))); putline(buf, mci); } @@ -1248,25 +1291,25 @@ errbody(mci, e, separator) } else { - (void) snprintf(buf, sizeof buf, "--%s", + (void) sm_strlcpyn(buf, sizeof buf, 2, "--", e->e_msgboundary); putline(buf, mci); - (void) snprintf(buf, sizeof buf, "Content-Type: %s", + (void) sm_strlcpyn(buf, sizeof buf, 2, "Content-Type: ", sendbody ? "message/rfc822" : "text/rfc822-headers"); putline(buf, mci); p = hvalue("Content-Transfer-Encoding", e->e_parent->e_header); - if (p != NULL && strcasecmp(p, "binary") != 0) + if (p != NULL && sm_strcasecmp(p, "binary") != 0) p = NULL; if (p == NULL && bitset(EF_HAS8BIT, e->e_parent->e_flags)) p = "8bit"; if (p != NULL) { - (void) snprintf(buf, sizeof buf, + (void) sm_snprintf(buf, sizeof buf, "Content-Transfer-Encoding: %s", p); putline(buf, mci); @@ -1292,11 +1335,12 @@ errbody(mci, e, separator) if (e->e_msgboundary != NULL) { putline("", mci); - (void) snprintf(buf, sizeof buf, "--%s--", e->e_msgboundary); + (void) sm_strlcpyn(buf, sizeof buf, 3, "--", e->e_msgboundary, + "--"); putline(buf, mci); } putline("", mci); - (void) fflush(mci->mci_out); + (void) sm_io_flush(mci->mci_out, SM_TIME_DEFAULT); /* ** Cleanup and exit @@ -1305,7 +1349,7 @@ errbody(mci, e, separator) if (errno != 0) syserr("errbody: I/O error"); } -/* +/* ** SMTPTODSN -- convert SMTP to DSN status code ** ** Parameters: @@ -1313,6 +1357,11 @@ errbody(mci, e, separator) ** ** Returns: ** The DSN version of the status code. +** +** Storage Management: +** smtptodsn() returns a pointer to a character string literal, +** which will remain valid forever, and thus does not need to +** be copied. Current code relies on this property. */ char * @@ -1370,7 +1419,7 @@ smtptodsn(smtpstat) return "4.0.0"; return "5.0.0"; } -/* +/* ** XTEXTIFY -- take regular text and turn it into DSN-style xtext ** ** Parameters: @@ -1407,6 +1456,11 @@ xtextify(t, taboo) nbogus++; l++; } + if (nbogus < 0) + { + /* since nbogus is ssize_t and wrapped, 2 * size_t would wrap */ + syserr("!xtextify string too long"); + } if (nbogus == 0) return t; l += nbogus * 2 + 1; @@ -1415,8 +1469,8 @@ xtextify(t, taboo) if (l > bplen) { if (bp != NULL) - sm_free(bp); - bp = xalloc(l); + sm_free(bp); /* XXX */ + bp = sm_pmalloc_x(l); bplen = l; } @@ -1439,7 +1493,7 @@ xtextify(t, taboo) *p = '\0'; return bp; } -/* +/* ** XUNTEXTIFY -- take xtext and turn it into plain text ** ** Parameters: @@ -1468,7 +1522,7 @@ xuntextify(t) if (l > bplen) { if (bp != NULL) - sm_free(bp); + sm_free(bp); /* XXX */ bp = xalloc(l); bplen = l; } @@ -1519,7 +1573,7 @@ xuntextify(t) *p = '\0'; return bp; } -/* +/* ** XTEXTOK -- check if a string is legal xtext ** ** Xtext is used in Delivery Status Notifications. The spec was @@ -1530,8 +1584,8 @@ xuntextify(t) ** s -- the string to check. ** ** Returns: -** TRUE -- if 's' is legal xtext. -** FALSE -- if it has any illegal characters in it. +** true -- if 's' is legal xtext. +** false -- if it has any illegal characters in it. */ bool @@ -1546,17 +1600,17 @@ xtextok(s) { c = *s++; if (!isascii(c) || !isxdigit(c)) - return FALSE; + return false; c = *s++; if (!isascii(c) || !isxdigit(c)) - return FALSE; + return false; } else if (c < '!' || c > '~' || c == '=') - return FALSE; + return false; } - return TRUE; + return true; } -/* +/* ** PRUNEROUTE -- prune an RFC-822 source route ** ** Trims down a source route to the last internet-registered hop. @@ -1566,8 +1620,8 @@ xtextok(s) ** addr -- the address ** ** Returns: -** TRUE -- address was modified -** FALSE -- address could not be pruned +** true -- address was modified +** false -- address could not be pruned ** ** Side Effects: ** modifies addr in-place @@ -1580,6 +1634,7 @@ pruneroute(addr) #if NAMED_BIND char *start, *at, *comma; char c; + int braclev; int rcode; int i; char hostbuf[BUFSIZ]; @@ -1587,37 +1642,60 @@ pruneroute(addr) /* check to see if this is really a route-addr */ if (*addr != '<' || addr[1] != '@' || addr[strlen(addr) - 1] != '>') - return FALSE; - start = strchr(addr, ':'); + return false; + + /* + ** Can't simply find the first ':' is the address might be in the + ** form: "<@[IPv6:::1]:user@host>" and the first ':' in inside + ** the IPv6 address. + */ + + start = addr; + braclev = 0; + while (*start != '\0') + { + if (*start == ':' && braclev <= 0) + break; + else if (*start == '[') + braclev++; + else if (*start == ']' && braclev > 0) + braclev--; + start++; + } + if (braclev > 0 || *start != ':') + return false; + at = strrchr(addr, '@'); - if (start == NULL || at == NULL || at < start) - return FALSE; + if (at == NULL || at < start) + return false; /* slice off the angle brackets */ i = strlen(at + 1); - if (i >= (SIZE_T) sizeof hostbuf) - return FALSE; - (void) strlcpy(hostbuf, at + 1, sizeof hostbuf); + if (i >= sizeof hostbuf) + return false; + (void) sm_strlcpy(hostbuf, at + 1, sizeof hostbuf); hostbuf[i - 1] = '\0'; - while (start) + while (start != NULL) { - if (getmxrr(hostbuf, mxhosts, NULL, FALSE, &rcode) > 0) + if (getmxrr(hostbuf, mxhosts, NULL, false, + &rcode, true, NULL) > 0) { - (void) strlcpy(addr + 1, start + 1, strlen(addr) - 1); - return TRUE; + (void) sm_strlcpy(addr + 1, start + 1, + strlen(addr) - 1); + return true; } c = *start; *start = '\0'; comma = strrchr(addr, ','); if (comma != NULL && comma[1] == '@' && - strlen(comma + 2) < (SIZE_T) sizeof hostbuf) - (void) strlcpy(hostbuf, comma + 2, sizeof hostbuf); + strlen(comma + 2) < sizeof hostbuf) + (void) sm_strlcpy(hostbuf, comma + 2, sizeof hostbuf); else comma = NULL; *start = c; start = comma; } #endif /* NAMED_BIND */ - return FALSE; + return false; } diff --git a/contrib/sendmail/src/sendmail.8 b/contrib/sendmail/src/sendmail.8 index 4d9bce4..d440774 100644 --- a/contrib/sendmail/src/sendmail.8 +++ b/contrib/sendmail/src/sendmail.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" Copyright (c) 1983, 1997 Eric P. Allman. All rights reserved. .\" Copyright (c) 1988, 1991, 1993 @@ -9,11 +9,11 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: sendmail.8,v 8.36.8.3 2000/12/14 23:08:15 gshapiro Exp $ +.\" $Id: sendmail.8,v 8.49 2001/03/23 22:10:00 ca Exp $ .\" .\" $FreeBSD$ .\" -.TH SENDMAIL 8 "$Date: 2000/12/14 23:08:15 $" +.TH SENDMAIL 8 "$Date: 2001/03/23 22:10:00 $" .SH NAME sendmail \- an electronic mail transport agent @@ -69,6 +69,14 @@ and `group' includes `john' in the expansion, then the letter will also be delivered to `john'. .SS Parameters .TP +.B \-Ac +Use submit.cf even if the operation mode does not indicate +an initial mail submission. +.TP +.B \-Am +Use sendmail.cf even if the operation mode indicates +an initial mail submission. +.TP .BI \-B type Set the body type to .IR type . @@ -115,7 +123,11 @@ Initialize the alias database. Deliver mail in the usual way (default). .TP .B \-bp -Print a listing of the queue. +Print a listing of the queue(s). +.TP +.B \-bP +Print number of entries in the queue(s); +only available with shared memory support. .TP .B \-bs Use the @@ -239,7 +251,7 @@ This can be a simple protocol name such as ``UUCP'' or a protocol and hostname, such as ``UUCP:ucbvax''. .TP \fB\-q\fR[\fItime\fR] -Processed saved messages in the queue at given intervals. +Process saved messages in the queue at given intervals. If .I time is omitted, process the queue once. @@ -249,7 +261,7 @@ with `s' being seconds, `m' -being minutes, +being minutes (default), `h' being hours, `d' @@ -262,28 +274,50 @@ For example, or `\-q90m' would both set the timeout to one hour thirty minutes. -If -.I time -is specified, +By default, .B sendmail -will run in the background. +will run in the background. This option can be used safely with .BR \-bd . .TP -.BI \-qI substr +\fB\-qp\fR[\fItime\fR] +Similar to \fB\-q\fItime\fR, +except that instead of periodically forking a child to process the queue, +sendmail forks a single persistent child for each queue +that alternates between processing the queue and sleeping. +The sleep time is given as the argument; it defaults to 1 second. +The process will always sleep at least 5 seconds if the queue was +empty in the previous queue run. +.TP +\fB\-q\fRf +Process saved messages in the queue once and do not fork(), +but run in the foreground. +.TP +\fB\-q\fRG name +Process jobs in queue group called +.I name +only. +.TP +\fB\-q\fR[\fI!\fR]I substr Limit processed jobs to those containing .I substr -as a substring of the queue id. +as a substring of the queue id or not when +.I ! +is specified. .TP -.BI \-qR substr +\fB\-q\fR[\fI!\fR]R substr Limit processed jobs to those containing .I substr -as a substring of one of the recipients. +as a substring of one of the recipients or not when +.I ! +is specified. .TP -.BI \-qS substr +\fB\-q\fR[\fI!\fR]S substr Limit processed jobs to those containing .I substr -as a substring of the sender. +as a substring of the sender or not when +.I ! +is specified. .TP .BI "\-R " return Set the amount of the message to be returned @@ -307,18 +341,6 @@ Read message for recipients. To:, Cc:, and Bcc: lines will be scanned for recipient addresses. The Bcc: line will be deleted before transmission. .TP -.B \-U -Initial (user) submission. This should -.I always -be set when called from a user agent such as -.B Mail -or -.B exmh -and -.I never -be set when called by a network delivery agent such as -.BR rmail . -.TP .BI "\-V " envid Set the original envelope id. This is propagated across SMTP to servers that support DSNs diff --git a/contrib/sendmail/vacation/vacation.1 b/contrib/sendmail/vacation/vacation.1 index 8631688..a996334 100644 --- a/contrib/sendmail/vacation/vacation.1 +++ b/contrib/sendmail/vacation/vacation.1 @@ -9,33 +9,36 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: vacation.1,v 8.11.4.8 2001/07/20 04:19:38 gshapiro Exp $ +.\" $Id: vacation.1,v 8.26 2001/11/21 04:21:35 gshapiro Exp $ .\" .\" $FreeBSD$ .\" -.TH VACATION 1 "$Date: 2001/07/20 04:19:38 $" +.TH VACATION 1 "$Date: 2001/11/21 04:21:35 $" .SH NAME vacation \- return ``I am not here'' indication .SH SYNOPSIS .B vacation -.RB [ \-i ] -.RB [ \-I ] -.RB [ \-r -.IR interval ] -.RB [ \-x ] .RB [ \-a .IR alias ] +.RB [ \-C +.IR cffile ] .RB [ \-d ] .RB [ \-f .IR database ] +.RB [ \-i ] +.RB [ \-I ] .RB [ \-l ] .RB [ \-m .IR message ] +.RB [ \-r +.IR interval ] .RB [ \-s .IR address ] .RB [ \-t .IR time ] +.RB [ \-U ] +.RB [ \-x ] .RB [ \-z ] .I login .SH DESCRIPTION @@ -63,6 +66,14 @@ Handle messages for in the same manner as those received for the user's login name. .TP +.BI \-C " cfpath" +Specify pathname of the sendmail configuration file. +This option is ignored if +.B \-U +is specified. +This option defaults to the standard sendmail configuration file, +located at /etc/mail/sendmail.cf on most systems. +.TP .B \-d Send error/debug messages to stdout instead of syslog. Otherwise, fatal errors, such as calling @@ -76,7 +87,9 @@ syslog(8). Use .I filename as name of the database instead of -.IR ~/.vacation.db . +.IR ~/.vacation.db +or +.IR ~/.vacation.{dir,pag} . Unless the .I filename starts with / it is relative to ~. @@ -92,10 +105,6 @@ Same as .B \-i (for backwards compatibility). .TP -.B \-l -List the content of the vacation database file including the address -and the associated time of the last auto-response to that address. -.TP .BI \-m " filename" Use .I filename @@ -105,6 +114,10 @@ Unless the .I filename starts with / it is relative to ~. .TP +.B \-l +List the content of the vacation database file including the address +and the associated time of the last auto-response to that address. +.TP .BI \-r " interval" Set the reply interval to .I interval @@ -125,6 +138,13 @@ line as the recipient for the vacation message. Ignored, available only for compatibility with Sun's vacation program. .TP +.B \-U +Do not attempt to lookup +.I login +in the password file. +The -f and -m options must be used to specify the database and message file +since there is no home directory for the default settings for these options. +.TP .B \-x reads an exclusion list from stdin (one address per line). Mails coming from an address @@ -170,8 +190,12 @@ or line is included in the mail headers. The people who have sent you messages are maintained as a db(3) +or +dbm(3) database in the file .I .vacation.db +or +.I .vacation.{dir,pag} in your home directory. .PP .B Vacation @@ -201,17 +225,13 @@ Sendmail(8) includes this ``From'' line automatically. -.PP -Fatal errors, such as calling -.B vacation -with incorrect arguments, or with non-existent -.IR login s, -are logged in the system log file, using -syslog(8). .SH FILES .TP 1.8i ~/.vacation.db -default database file +default database file for db(3) +.TP 1.8i +~/.vacation.{dir,pag} +default database file for dbm(3) .TP ~/.vacation.msg default message to send |