mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-05 09:14:03 +00:00
Fix conflicts from merge of sendmail 8.11.0.
PR: bin/11552 misc/18512 bin/15088
This commit is contained in:
parent
e8c96e01af
commit
3299c2f123
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64565
@ -1,5 +1,6 @@
|
||||
#
|
||||
# Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
# Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 1983, 1995 Eric P. Allman. All rights reserved.
|
||||
# Copyright (c) 1988, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
@ -8,6 +9,7 @@
|
||||
# forth in the LICENSE file which can be found at the top level of
|
||||
# the sendmail distribution.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
######################################################################
|
||||
@ -15,10 +17,11 @@
|
||||
#####
|
||||
##### SENDMAIL CONFIGURATION FILE
|
||||
#####
|
||||
define(`TEMPFILE', maketemp(/tmp/cfXXXXXX))dnl
|
||||
ifdef(`unix', `dnl
|
||||
ifdef(`TEMPFILE', `dnl', `define(`TEMPFILE', maketemp(/tmp/cfXXXXXX))dnl
|
||||
syscmd(sh _CF_DIR_`'sh/makeinfo.sh _CF_DIR_ > TEMPFILE)dnl
|
||||
include(TEMPFILE)dnl
|
||||
syscmd(rm -f TEMPFILE)dnl
|
||||
syscmd(rm -f TEMPFILE)dnl')', `dnl')
|
||||
#####
|
||||
######################################################################
|
||||
######################################################################
|
||||
@ -36,16 +39,85 @@ define(`PUSHDIVERT', `pushdef(`__D__', divnum)divert($1)')
|
||||
define(`POPDIVERT', `divert(__D__)popdef(`__D__')')
|
||||
define(`OSTYPE',
|
||||
`PUSHDIVERT(-1)
|
||||
ifdef(`__OSTYPE__', `errprint(`duplicate OSTYPE'($1))')
|
||||
ifdef(`__OSTYPE__', `errprint(`duplicate OSTYPE'($1)
|
||||
)')
|
||||
define(`__OSTYPE__', $1)
|
||||
define(`_ARG_', $2)
|
||||
include(_CF_DIR_`'ostype/$1.m4)POPDIVERT`'')
|
||||
## 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')
|
||||
define(`_ACC_ARG_3_',`$3')
|
||||
define(`_ACC_ARG_4_',`$4')
|
||||
define(`_ACC_ARG_5_',`$5')
|
||||
define(`_ACC_ARG_6_',`$6')
|
||||
define(`_ACC_ARG_7_',`$7')
|
||||
define(`_ACC_ARG_8_',`$8')
|
||||
define(`_ACC_ARG_9_',`$9')
|
||||
define(`_ARG1_',`_ACC_ARG_1_(_ARGS_)')
|
||||
define(`_ARG2_',`_ACC_ARG_2_(_ARGS_)')
|
||||
define(`_ARG3_',`_ACC_ARG_3_(_ARGS_)')
|
||||
define(`_ARG4_',`_ACC_ARG_4_(_ARGS_)')
|
||||
define(`_ARG5_',`_ACC_ARG_5_(_ARGS_)')
|
||||
define(`_ARG6_',`_ACC_ARG_6_(_ARGS_)')
|
||||
define(`_ARG7_',`_ACC_ARG_7_(_ARGS_)')
|
||||
define(`_ARG8_',`_ACC_ARG_8_(_ARGS_)')
|
||||
define(`_ARG9_',`_ACC_ARG_9_(_ARGS_)')
|
||||
dnl define if not yet defined: if `$1' is not defined it will be `$2'
|
||||
define(`_DEFIFNOT',`ifdef(`$1',`',`define(`$1',`$2')')')
|
||||
dnl ----------------------------------------
|
||||
dnl add a char $2 to a string $1 if it is not there
|
||||
define(`_ADDCHAR_',`define(`_I_',`eval(index(`$1',`$2') >= 0)')`'ifelse(_I_,`1',`$1',`$1$2')')
|
||||
dnl ----
|
||||
dnl delete a char $2 from a string $1 if it is there
|
||||
define(`_DELCHAR_',`define(`_IDX_',`index(`$1',`$2')')`'define(`_I_',`eval(_IDX_ >= 0)')`'ifelse(_I_,`1',`substr(`$1',0,_IDX_)`'substr(`$1',eval(_IDX_+1))',`$1')')
|
||||
dnl ----
|
||||
dnl apply a macro to a whole string by recursion (one char at a time)
|
||||
dnl $1: macro
|
||||
dnl $2: first argument to macro
|
||||
dnl $3: list that is split up into characters
|
||||
define(`_AP_',`ifelse(`$3',`',`$2',`_AP_(`$1',$1(`$2',substr(`$3',0,1)),substr(`$3',1))')')
|
||||
dnl ----
|
||||
dnl MODIFY_MAILER_FLAGS: append tail of $2 to $1_MF_A/D_
|
||||
dnl A if head($2) = +
|
||||
dnl D if head($2) = -
|
||||
dnl $1_MF_ is set otherwise; set _A/D_ to `'
|
||||
define(`MODIFY_MAILER_FLAGS',`define(`_hd_',`substr(`$2',0,1)')define(`_tl_',`substr(`$2',1)')`'ifelse(_hd_,`+',`ifdef($1`'_MF_A_, `define($1`'_MF_A_,$1_MF_A_`'_tl_)', `define($1`'_MF_A_, _tl_)')',_hd_,`-',`ifdef($1`'_MF_D_, `define($1`'_MF_D_,$1_MF_D_`'_tl_)', `define($1`'_MF_D_,_tl_)')',`define($1`'_MF_,`$2')define($1`'_MF_A_,`')define($1`'_MF_D_,`')')')
|
||||
dnl ----
|
||||
dnl actually modify flags:
|
||||
dnl $1: flags (strings) to modify
|
||||
dnl $2: name of flags (just first part) to modify
|
||||
dnl WARNING: the order might be important: if someone adds and delete the
|
||||
dnl same characters, he does not deserve any better, does he?
|
||||
dnl this could be coded more efficiently... (do not apply the macro if _MF_A/D_ is undefined)
|
||||
define(`_MODMF_',`ifdef($2`'_MF_,`$2_MF_',`_AP_(`_ADDCHAR_',_AP_(`_DELCHAR_',$1,ifdef($2`'_MF_D_,`$2_MF_D_',`')),ifdef($2`'_MF_A_,`$2_MF_A_',`'))')')
|
||||
dnl usage:
|
||||
dnl MODIFY_MAILER_FLAGS(`LOCAL',`+FlaGs')dnl
|
||||
dnl in MAILER.m4: _MODMF_(LMF,`LOCAL')
|
||||
dnl ----------------------------------------
|
||||
define(`MAILER',
|
||||
`ifdef(`_MAILER_$1_', `dnl`'',
|
||||
`define(`_MAILER_$1_', `')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)include(_CF_DIR_`'feature/$1.m4)POPDIVERT`'')
|
||||
define(`HACK', `PUSHDIVERT(-1)define(`_ARG_', $2)include(_CF_DIR_`'hack/$1.m4)POPDIVERT`'')
|
||||
`define(`_M_N_', `ifelse(`$2', `', `$1', `$2')')dnl
|
||||
ifdef(_MAILER_`'_M_N_`'_, `dnl`'',
|
||||
`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(`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(`_MAIL_FILTERS_', `')
|
||||
define(`MAIL_FILTER', `define(`_MAIL_FILTERS_', defn(`_MAIL_FILTERS_')
|
||||
X`'$1`, '`$2')')
|
||||
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(`VERSIONID', ``##### $1 #####'')
|
||||
define(`LOCAL_RULE_0', `divert(3)')
|
||||
define(`LOCAL_RULE_1',
|
||||
@ -54,7 +126,7 @@ define(`LOCAL_RULE_1',
|
||||
### Ruleset 1 -- Sender Rewriting ###
|
||||
#######################################
|
||||
|
||||
S1
|
||||
Ssender=1
|
||||
')
|
||||
define(`LOCAL_RULE_2',
|
||||
`divert(9)dnl
|
||||
@ -62,7 +134,7 @@ define(`LOCAL_RULE_2',
|
||||
### Ruleset 2 -- Recipient Rewriting ###
|
||||
##########################################
|
||||
|
||||
S2
|
||||
Srecipient=2
|
||||
')
|
||||
define(`LOCAL_RULESETS',
|
||||
`divert(9)
|
||||
@ -90,31 +162,66 @@ POPDIVERT`'dnl`'')
|
||||
define(`MASQUERADE_AS', `define(`MASQUERADE_NAME', $1)')
|
||||
define(`MASQUERADE_DOMAIN', `PUSHDIVERT(5)CM$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`MASQUERADE_EXCEPTION', `PUSHDIVERT(5)CN$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`MASQUERADE_DOMAIN_FILE', `PUSHDIVERT(5)FM$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`LOCAL_DOMAIN', `PUSHDIVERT(5)Cw$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`CANONIFY_DOMAIN', `PUSHDIVERT(5)C{Canonify}$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`CANONIFY_DOMAIN_FILE', `PUSHDIVERT(5)F{Canonify}$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`GENERICS_DOMAIN', `PUSHDIVERT(5)CG$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`GENERICS_DOMAIN_FILE', `PUSHDIVERT(5)FG$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`LDAPROUTE_DOMAIN', `PUSHDIVERT(5)C{LDAPRoute}$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`LDAPROUTE_DOMAIN_FILE', `PUSHDIVERT(5)F{LDAPRoute}$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`VIRTUSER_DOMAIN', `PUSHDIVERT(5)C{VirtHost}$1
|
||||
define(`_VIRTHOSTS_')
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`VIRTUSER_DOMAIN_FILE', `PUSHDIVERT(5)F{VirtHost}$1
|
||||
define(`_VIRTHOSTS_')
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`RELAY_DOMAIN', `PUSHDIVERT(5)CR$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`RELAY_DOMAIN_FILE', `PUSHDIVERT(5)FR$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`TRUST_AUTH_MECH', `PUSHDIVERT(5)C{TrustAuthMech}$1
|
||||
POPDIVERT`'dnl`'')
|
||||
define(`_OPTINS', `ifdef(`$1', `$2$1$3')')
|
||||
|
||||
|
||||
m4wrap(`include(_CF_DIR_`m4/proto.m4')')
|
||||
|
||||
# default location for files
|
||||
ifdef(`MAIL_SETTINGS_DIR', , `define(`MAIL_SETTINGS_DIR', `/etc/mail/')')
|
||||
|
||||
# set our default hashed database type
|
||||
define(`DATABASE_MAP_TYPE', `hash')
|
||||
|
||||
# set up default values for options
|
||||
define(`ALIAS_FILE', ifdef(`_USE_ETC_MAIL_', `/etc/mail/aliases', `/etc/aliases'))
|
||||
define(`ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases')
|
||||
define(`confMAILER_NAME', ``MAILER-DAEMON'')
|
||||
define(`confFROM_LINE', `From $g $d')
|
||||
define(`confFROM_LINE', `From $g $d')
|
||||
define(`confOPERATORS', `.:%@!^/[]+')
|
||||
define(`confSMTP_LOGIN_MSG', `$j Sendmail $v/$Z; $b')
|
||||
define(`confRECEIVED_HEADER', `$?sfrom $s $.$?_($?s$|from $.$_)
|
||||
$.by $j ($v/$Z)$?r with $r$. id $i$?u
|
||||
for $u; $|;
|
||||
$.$b$?g
|
||||
(envelope-from $g)$.')')
|
||||
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_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_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_BY_
|
||||
_REC_TLS_
|
||||
_REC_END_')
|
||||
define(`confSEVEN_BIT_INPUT', `False')
|
||||
define(`confEIGHT_BIT_HANDLING', `pass8')
|
||||
define(`confALIAS_WAIT', `10')
|
||||
@ -134,10 +241,15 @@ define(`confSAFE_QUEUE', `True')
|
||||
define(`confTO_QUEUERETURN', `5d')
|
||||
define(`confTO_QUEUEWARN', `4h')
|
||||
define(`confTIME_ZONE', `USE_SYSTEM')
|
||||
define(`confCW_FILE', ifdef(`_USE_ETC_MAIL_', `/etc/mail/local-host-names', `/etc/sendmail.cw'))
|
||||
define(`confCW_FILE', `MAIL_SETTINGS_DIR`'local-host-names')
|
||||
define(`confMIME_FORMAT_ERRORS', `True')
|
||||
define(`confFORWARD_PATH', `$z/.forward.$w:$z/.forward')
|
||||
define(`confCR_FILE', `-o /etc/mail/relay-domains')
|
||||
define(`confCR_FILE', `-o MAIL_SETTINGS_DIR`'relay-domains')
|
||||
define(`confMILTER_MACROS_CONNECT', ``j, _, {daemon_name}, {if_name}, {if_addr}'')
|
||||
define(`confMILTER_MACROS_HELO', ``{tls_version}, {cipher}, {cipher_bits}, {cert_subject}, {cert_issuer}'')
|
||||
define(`confMILTER_MACROS_ENVFROM', ``i, {auth_type}, {auth_authen}, {auth_ssf}, {auth_author}, {mail_mailer}, {mail_host}, {mail_addr}'')
|
||||
define(`confMILTER_MACROS_ENVRCPT', ``{rcpt_mailer}, {rcpt_host}, {rcpt_addr}'')
|
||||
|
||||
|
||||
divert(0)dnl
|
||||
VERSIONID(`@(#)cfhead.m4 8.23 (Berkeley) 10/6/1998')
|
||||
VERSIONID(`$Id: cfhead.m4,v 8.76.4.9 2000/07/11 23:50:30 geir Exp $')
|
||||
|
@ -1,6 +1,7 @@
|
||||
divert(-1)
|
||||
#
|
||||
# Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
# Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 1983 Eric P. Allman. All rights reserved.
|
||||
# Copyright (c) 1988, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
@ -9,13 +10,12 @@ divert(-1)
|
||||
# forth in the LICENSE file which can be found at the top level of
|
||||
# the sendmail distribution.
|
||||
#
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
divert(0)
|
||||
VERSIONID(`@(#)bsd4.4.m4 8.10 (Berkeley) 10/6/1998')
|
||||
ifdef(`HELP_FILE',, `define(`HELP_FILE', ifdef(`_USE_ETC_MAIL_', `/etc/mail/helpfile', `/usr/share/misc/sendmail.hf'))')dnl
|
||||
ifdef(`STATUS_FILE',, `define(`STATUS_FILE', ifdef(`_USE_ETC_MAIL_', `/etc/mail/statistics', `/var/log/sendmail.st'))')dnl
|
||||
VERSIONID(`$Id: bsd4.4.m4,v 8.14 1999/04/24 05:37:40 gshapiro Exp $')
|
||||
ifdef(`STATUS_FILE',, `define(`STATUS_FILE', `/var/log/sendmail.st')')dnl
|
||||
ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /usr/libexec/mail.local)')dnl
|
||||
ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail $u')')dnl
|
||||
ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -z -a$g $h!rmail ($u)')')dnl
|
||||
|
@ -1,6 +1,7 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
# Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 1983 Eric P. Allman. All rights reserved.
|
||||
# Copyright (c) 1988, 1993
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
@ -10,7 +11,9 @@
|
||||
# the sendmail distribution.
|
||||
#
|
||||
#
|
||||
# @(#)makeinfo.sh 8.11 (Berkeley) 5/19/1998
|
||||
# $Id: makeinfo.sh,v 8.14 1999/02/07 07:26:25 gshapiro Exp $
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
usewhoami=0
|
||||
|
@ -9,15 +9,17 @@
|
||||
* Change directory to "netinfo" and get the file internet.listing
|
||||
* The file is updated monthly.
|
||||
*
|
||||
* Feed the output of this program to "makemap hash /etc/bitdomain.db"
|
||||
* Feed the output of this program to "makemap hash /etc/mail/bitdomain.db"
|
||||
* to create the table used by the "FEATURE(bitdomain)" config file macro.
|
||||
* If your sendmail does not have the db library compiled in, you can instead
|
||||
* use "makemap dbm /etc/bitdomain" and
|
||||
* "FEATURE(bitdomain,`dbm -o /etc/bitdomain')"
|
||||
* use "makemap dbm /etc/mail/bitdomain" and
|
||||
* "FEATURE(bitdomain,`dbm -o /etc/mail/bitdomain')"
|
||||
*
|
||||
* The bitdomain table should be rebuilt monthly.
|
||||
*/
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
@ -187,7 +189,7 @@ char *domainlen;
|
||||
case NO_DATA:
|
||||
err = "registered in DNS, but not mailable";
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
err = "unknown nameserver error";
|
||||
break;
|
||||
@ -210,7 +212,7 @@ valhost(host, hbsize)
|
||||
int hbsize;
|
||||
{
|
||||
register u_char *eom, *ap;
|
||||
register int n;
|
||||
register int n;
|
||||
HEADER *hp;
|
||||
querybuf answer;
|
||||
int ancount, qdcount;
|
||||
@ -406,4 +408,4 @@ finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
.\" Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
.\" Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
@ -7,46 +8,60 @@
|
||||
.\" the sendmail distribution.
|
||||
.\"
|
||||
.\"
|
||||
.\" @(#)mail.local.8 8.7 (Berkeley) 5/19/1998
|
||||
.\" $Id: mail.local.8,v 8.14 1999/08/26 15:49:20 ca Exp $
|
||||
.\"
|
||||
.Dd May 19, 1998
|
||||
.Dt MAIL.LOCAL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mail.local
|
||||
.Nd store mail in a mailbox
|
||||
.Sh SYNOPSIS
|
||||
.Nm mail.local
|
||||
.Op Fl f Ar from
|
||||
.Op Fl b
|
||||
.Op Fl s
|
||||
.Ar user ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm Mail.local
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.TH MAIL.LOCAL 8 "$Date: 1999/08/26 15:49:20 $"
|
||||
.SH NAME
|
||||
.B mail.local
|
||||
\- store mail in a mailbox
|
||||
.SH SYNOPSIS
|
||||
.B mail.local
|
||||
.RB [ \-7 "] [" \-B "] [" \-d "] [" \-l "] [" \-s "] [" \-f
|
||||
.IR from "] " "user ..."
|
||||
.SH DESCRIPTION
|
||||
.B Mail.local
|
||||
reads the standard input up to an end-of-file and appends it to each
|
||||
.Ar user's
|
||||
.Pa mail
|
||||
file.
|
||||
The
|
||||
.Ar user
|
||||
.I user's
|
||||
.B mail
|
||||
file. The
|
||||
.I user
|
||||
must be a valid user name.
|
||||
.Pp
|
||||
.PP
|
||||
The options are as follows:
|
||||
.Bl -tag -width xxxfrom
|
||||
.It Fl f Ar from
|
||||
Specify the sender's name.
|
||||
.It Fl b
|
||||
.TP 1i
|
||||
.B \-7
|
||||
Do not advertise 8BITMIME support in LMTP mode.
|
||||
.TP
|
||||
.B \-B
|
||||
Turn off the attempts to notify the
|
||||
.Dq biff
|
||||
service.
|
||||
.It Fl s
|
||||
.TP
|
||||
.B \-b
|
||||
Return a permanent error instead of a temporary error
|
||||
if a mailbox exceeds quota.
|
||||
.TP
|
||||
.B \-d
|
||||
Specify this is a delivery (for backward compatibility).
|
||||
.TP
|
||||
.BI \-f " from"
|
||||
Specify the sender's name.
|
||||
.TP
|
||||
.B \-l
|
||||
Turn on LMTP mode.
|
||||
.TP
|
||||
.B \-s
|
||||
Turn off the
|
||||
.Xr fsync 2
|
||||
call that forces the mailbox to be committed to disk before returning a
|
||||
.Dq success
|
||||
status.
|
||||
.El
|
||||
.Pp
|
||||
.TP
|
||||
.BI \-r " from"
|
||||
Specify the sender's name (for backward compatibility).
|
||||
.PP
|
||||
Individual mail messages in the mailbox are delimited by an empty
|
||||
line followed by a line beginning with the string ``From ''.
|
||||
A line containing the string ``From '', the sender's name and a time stamp
|
||||
@ -57,47 +72,48 @@ which could be mistaken for a ``From '' delimiter line
|
||||
(that is,
|
||||
a line beginning with the five characters
|
||||
``From '' following a blank line).
|
||||
.Pp
|
||||
.PP
|
||||
The mail files are exclusively locked with
|
||||
.Xr flock 2
|
||||
while mail is appended,
|
||||
flock(2)
|
||||
while mail is appended,
|
||||
and a
|
||||
.Pa user.lock
|
||||
file also is created while the mailbox is locked
|
||||
.B user.lock
|
||||
file also is created while the mailbox is locked
|
||||
for compatibility with older MUAs.
|
||||
.Pp
|
||||
If the ``biff'' service is returned by
|
||||
.Xr getservbyname 3 ,
|
||||
.PP
|
||||
If the ``biff'' service is returned by
|
||||
getservbyname(3),
|
||||
the biff server is notified of delivered mail.
|
||||
.Pp
|
||||
.PP
|
||||
The
|
||||
.Nm mail.local
|
||||
.B mail.local
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh ENVIRONMENT
|
||||
.Bl -tag -width indent
|
||||
.It Ev TZ
|
||||
.SH ENVIRONMENT
|
||||
.IP TZ
|
||||
Used to set the appropriate time zone on the timestamp.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /tmp/local.XXXXXX -compact
|
||||
.It Pa /tmp/local.XXXXXX
|
||||
.SH FILES
|
||||
.PD 0.2v
|
||||
.TP 2.2i
|
||||
/tmp/local.XXXXXX
|
||||
temporary files
|
||||
.It Pa /var/mail/user
|
||||
.TP
|
||||
/var/mail/user
|
||||
user's mailbox directory
|
||||
.It Pa /var/mail/user.lock
|
||||
.TP
|
||||
/var/mail/user.lock
|
||||
lock file for a user's mailbox
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mail 1 ,
|
||||
.Xr flock 2 ,
|
||||
.Xr getservbyname 3 ,
|
||||
.Xr comsat 8 ,
|
||||
.Xr sendmail 8
|
||||
.Sh HISTORY
|
||||
.PD
|
||||
.SH SEE ALSO
|
||||
mail(1),
|
||||
flock(2),
|
||||
getservbyname(3),
|
||||
comsat(8),
|
||||
sendmail(8)
|
||||
.SH HISTORY
|
||||
A superset of
|
||||
.Nm mail.local
|
||||
.B mail.local
|
||||
(handling mailbox reading as well as mail delivery)
|
||||
appeared in
|
||||
.At v7 .
|
||||
appeared in
|
||||
Version 7 AT&T UNIX
|
||||
as the program
|
||||
.Nm mail .
|
||||
.BR mail .
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
* Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1983 Eric P. Allman. All rights reserved.
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -13,33 +14,45 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1988, 1993\n\
|
||||
"@(#) Copyright (c) 1998, 1999 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 /* not lint */
|
||||
#endif /* ! lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)mailstats.c 8.29 (Berkeley) 1/25/1999";
|
||||
#endif /* not lint */
|
||||
static char id[] = "@(#)$Id: mailstats.c,v 8.53.16.10 2000/07/18 05:51:15 gshapiro Exp $";
|
||||
#endif /* ! lint */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#ifdef EX_OK
|
||||
# undef EX_OK /* unistd.h may have another use for this */
|
||||
#endif /* EX_OK */
|
||||
#include <sysexits.h>
|
||||
|
||||
#include <sendmail/sendmail.h>
|
||||
#include <sendmail/mailstats.h>
|
||||
#include <sendmail/pathnames.h>
|
||||
|
||||
#ifndef NOT_SENDMAIL
|
||||
# define NOT_SENDMAIL
|
||||
#endif
|
||||
#include <sendmail.h>
|
||||
#include <mailstats.h>
|
||||
#include <pathnames.h>
|
||||
|
||||
#define MNAMELEN 20 /* max length of mailer name */
|
||||
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
struct statistics stat;
|
||||
register int i;
|
||||
int mno;
|
||||
int save_errno;
|
||||
int ch, fd;
|
||||
char *sfile;
|
||||
char *cfile;
|
||||
@ -48,11 +61,15 @@ main(argc, argv)
|
||||
bool progmode;
|
||||
long frmsgs = 0, frbytes = 0, tomsgs = 0, tobytes = 0, rejmsgs = 0;
|
||||
long dismsgs = 0;
|
||||
char mtable[MAXMAILERS][MNAMELEN+1];
|
||||
time_t now;
|
||||
char mtable[MAXMAILERS][MNAMELEN + 1];
|
||||
char sfilebuf[MAXLINE];
|
||||
char buf[MAXLINE];
|
||||
time_t now;
|
||||
struct statistics stats;
|
||||
extern char *ctime();
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
|
||||
cfile = _PATH_SENDMAILCF;
|
||||
sfile = NULL;
|
||||
@ -74,22 +91,15 @@ main(argc, argv)
|
||||
mnames = FALSE;
|
||||
break;
|
||||
|
||||
#if _FFR_MAILSTATS_PROGMODE
|
||||
case 'p':
|
||||
progmode = TRUE;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case '?':
|
||||
default:
|
||||
usage:
|
||||
#if _FFR_MAILSTATS_PROGMODE
|
||||
fputs("usage: mailstats [-o] [-C cffile] [-f stfile] -o -p\n",
|
||||
stderr);
|
||||
#else
|
||||
fputs("usage: mailstats [-o] [-C cffile] [-f stfile] -o \n",
|
||||
stderr);
|
||||
#endif
|
||||
(void) fputs("usage: mailstats [-C cffile] [-f stfile] [-o] [-p]\n",
|
||||
stderr);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
}
|
||||
@ -101,15 +111,17 @@ main(argc, argv)
|
||||
|
||||
if ((cfp = fopen(cfile, "r")) == NULL)
|
||||
{
|
||||
save_errno = errno;
|
||||
fprintf(stderr, "mailstats: ");
|
||||
errno = save_errno;
|
||||
perror(cfile);
|
||||
exit(EX_NOINPUT);
|
||||
}
|
||||
|
||||
mno = 0;
|
||||
(void) strcpy(mtable[mno++], "prog");
|
||||
(void) strcpy(mtable[mno++], "*file*");
|
||||
(void) strcpy(mtable[mno++], "*include*");
|
||||
(void) strlcpy(mtable[mno++], "prog", MNAMELEN + 1);
|
||||
(void) strlcpy(mtable[mno++], "*file*", MNAMELEN + 1);
|
||||
(void) strlcpy(mtable[mno++], "*include*", MNAMELEN + 1);
|
||||
|
||||
while (fgets(buf, sizeof(buf), cfp) != NULL)
|
||||
{
|
||||
@ -141,14 +153,14 @@ main(argc, argv)
|
||||
}
|
||||
|
||||
/* this is the S or StatusFile option -- save it */
|
||||
if (strlen(b) >= sizeof sfilebuf)
|
||||
if (strlcpy(sfilebuf, b, sizeof sfilebuf) >=
|
||||
sizeof sfilebuf)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"StatusFile filename too long: %.30s...\n",
|
||||
b);
|
||||
exit(EX_CONFIG);
|
||||
}
|
||||
strcpy(sfilebuf, b);
|
||||
b = strchr(sfilebuf, '#');
|
||||
if (b == NULL)
|
||||
b = strchr(sfilebuf, '\n');
|
||||
@ -172,7 +184,7 @@ main(argc, argv)
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
m = mtable[mno];
|
||||
s = m + MNAMELEN; /* is [MNAMELEN+1] */
|
||||
s = m + MNAMELEN; /* is [MNAMELEN + 1] */
|
||||
while (*b != ',' && !(isascii(*b) && isspace(*b)) &&
|
||||
*b != '\0' && m < s)
|
||||
*m++ = *b++;
|
||||
@ -195,66 +207,70 @@ main(argc, argv)
|
||||
exit (EX_OSFILE);
|
||||
}
|
||||
|
||||
if ((fd = open(sfile, O_RDONLY)) < 0 ||
|
||||
(i = read(fd, &stat, sizeof stat)) < 0)
|
||||
fd = open(sfile, O_RDONLY);
|
||||
if ((fd < 0) || (i = read(fd, &stats, sizeof stats)) < 0)
|
||||
{
|
||||
fputs("mailstats: ", stderr);
|
||||
save_errno = errno;
|
||||
(void) fputs("mailstats: ", stderr);
|
||||
errno = save_errno;
|
||||
perror(sfile);
|
||||
exit(EX_NOINPUT);
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
sleep(1);
|
||||
if ((i = read(fd, &stat, sizeof stat)) < 0)
|
||||
(void) sleep(1);
|
||||
if ((i = read(fd, &stats, sizeof stats)) < 0)
|
||||
{
|
||||
fputs("mailstats: ", stderr);
|
||||
save_errno = errno;
|
||||
(void) fputs("mailstats: ", stderr);
|
||||
errno = save_errno;
|
||||
perror(sfile);
|
||||
exit(EX_NOINPUT);
|
||||
}
|
||||
else if (i == 0)
|
||||
{
|
||||
bzero((ARBPTR_T) &stat, sizeof stat);
|
||||
(void) time(&stat.stat_itime);
|
||||
memset((ARBPTR_T) &stats, '\0', sizeof stats);
|
||||
(void) time(&stats.stat_itime);
|
||||
}
|
||||
}
|
||||
if (i != 0)
|
||||
{
|
||||
if (stat.stat_magic != STAT_MAGIC)
|
||||
if (stats.stat_magic != STAT_MAGIC)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"mailstats: incorrect magic number in %s\n",
|
||||
sfile);
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
else if (stat.stat_version != STAT_VERSION)
|
||||
else if (stats.stat_version != STAT_VERSION)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"mailstats version (%d) incompatible with %s version(%d)\n",
|
||||
STAT_VERSION, sfile, stat.stat_version);
|
||||
"mailstats version (%d) incompatible with %s version (%d)\n",
|
||||
STAT_VERSION, sfile, stats.stat_version);
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
else if (i != sizeof stat || stat.stat_size != sizeof(stat))
|
||||
else if (i != sizeof stats || stats.stat_size != sizeof(stats))
|
||||
{
|
||||
fputs("mailstats: file size changed.\n", stderr);
|
||||
(void) fputs("mailstats: file size changed.\n", stderr);
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
}
|
||||
|
||||
if (progmode)
|
||||
{
|
||||
time(&now);
|
||||
printf("%ld %ld\n", (long) stat.stat_itime, (long) now);
|
||||
(void) time(&now);
|
||||
printf("%ld %ld\n", (long) stats.stat_itime, (long) now);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Statistics from %s", ctime(&stat.stat_itime));
|
||||
printf("Statistics from %s", ctime(&stats.stat_itime));
|
||||
printf(" M msgsfr bytes_from msgsto bytes_to msgsrej msgsdis%s\n",
|
||||
mnames ? " Mailer" : "");
|
||||
}
|
||||
for (i = 0; i < MAXMAILERS; i++)
|
||||
{
|
||||
if (stat.stat_nf[i] || stat.stat_nt[i] ||
|
||||
stat.stat_nr[i] || stat.stat_nd[i])
|
||||
if (stats.stat_nf[i] || stats.stat_nt[i] ||
|
||||
stats.stat_nr[i] || stats.stat_nd[i])
|
||||
{
|
||||
char *format;
|
||||
|
||||
@ -263,34 +279,40 @@ main(argc, argv)
|
||||
else
|
||||
format = "%2d %8ld %10ldK %8ld %10ldK %6ld %6ld";
|
||||
printf(format, i,
|
||||
stat.stat_nf[i], stat.stat_bf[i],
|
||||
stat.stat_nt[i], stat.stat_bt[i],
|
||||
stat.stat_nr[i], stat.stat_nd[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 (mnames)
|
||||
printf(" %s", mtable[i]);
|
||||
printf("\n");
|
||||
frmsgs += stat.stat_nf[i];
|
||||
frbytes += stat.stat_bf[i];
|
||||
tomsgs += stat.stat_nt[i];
|
||||
tobytes += stat.stat_bt[i];
|
||||
rejmsgs += stat.stat_nr[i];
|
||||
dismsgs += stat.stat_nd[i];
|
||||
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 (progmode)
|
||||
{
|
||||
printf(" T %8ld %10ld %8ld %10ld %6ld %6ld\n",
|
||||
frmsgs, frbytes, tomsgs, tobytes, rejmsgs, dismsgs);
|
||||
close(fd);
|
||||
printf(" 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)
|
||||
close(fd);
|
||||
(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);
|
||||
}
|
||||
exit(EX_OK);
|
||||
/* NOTREACHED */
|
||||
return EX_OK;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
* Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1983 Eric P. Allman. All rights reserved.
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -12,74 +13,86 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1988, 1993\n\
|
||||
"@(#) Copyright (c) 1998-2000 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 /* not lint */
|
||||
#endif /* ! lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)praliases.c 8.21 (Berkeley) 12/27/1998";
|
||||
#endif /* not lint */
|
||||
static char id[] = "@(#)$Id: praliases.c,v 8.59.4.10 2000/07/18 05:41:39 gshapiro Exp $";
|
||||
#endif /* ! lint */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#ifdef EX_OK
|
||||
# undef EX_OK /* unistd.h may have another use for this */
|
||||
#endif /* EX_OK */
|
||||
#include <sysexits.h>
|
||||
|
||||
#if !defined(NDBM) && !defined(NEWDB)
|
||||
ERROR README: You must define one of NDBM or NEWDB in order to compile
|
||||
ERROR README: praliases.
|
||||
#endif
|
||||
|
||||
#ifdef NDBM
|
||||
# include <ndbm.h>
|
||||
#endif
|
||||
#ifndef NOT_SENDMAIL
|
||||
# define NOT_SENDMAIL
|
||||
#endif
|
||||
#include <sendmail.h>
|
||||
#include <pathnames.h>
|
||||
#ifdef NEWDB
|
||||
# include <db.h>
|
||||
# ifndef DB_VERSION_MAJOR
|
||||
# define DB_VERSION_MAJOR 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(IRIX64) || defined(IRIX5) || defined(IRIX6) || \
|
||||
defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__)
|
||||
# ifndef HASSTRERROR
|
||||
# define HASSTRERROR 1 /* has strerror(3) */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HASSTRERROR
|
||||
extern char *strerror __P((int));
|
||||
#endif
|
||||
#endif /* ! NOT_SENDMAIL */
|
||||
#include <sendmail/sendmail.h>
|
||||
#include <sendmail/pathnames.h>
|
||||
#include <libsmdb/smdb.h>
|
||||
|
||||
static void praliases __P((char *, int, char **));
|
||||
#ifdef NDBM
|
||||
static void praliases_dbm __P((char *, int, char **));
|
||||
#endif
|
||||
|
||||
uid_t RealUid;
|
||||
gid_t RealGid;
|
||||
char *RealUserName;
|
||||
uid_t RunAsUid;
|
||||
uid_t RunAsGid;
|
||||
char *RunAsUserName;
|
||||
int Verbose = 2;
|
||||
bool DontInitGroups = FALSE;
|
||||
uid_t TrustedUid = 0;
|
||||
BITMAP256 DontBlameSendmail;
|
||||
|
||||
extern void syserr __P((const char *, ...));
|
||||
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
char *cfile;
|
||||
#if _FFR_GRAB_ALIASFILE_OPTION
|
||||
char *filename = NULL;
|
||||
#else
|
||||
char *filename = "/etc/aliases";
|
||||
#endif
|
||||
FILE *cfp;
|
||||
int ch;
|
||||
char afilebuf[MAXLINE];
|
||||
char buf[MAXLINE];
|
||||
struct passwd *pw;
|
||||
static char rnamebuf[MAXNAME];
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
|
||||
clrbitmap(DontBlameSendmail);
|
||||
RunAsUid = RealUid = getuid();
|
||||
RunAsGid = RealGid = getgid();
|
||||
pw = getpwuid(RealUid);
|
||||
if (pw != NULL)
|
||||
{
|
||||
if (strlen(pw->pw_name) > MAXNAME - 1)
|
||||
pw->pw_name[MAXNAME] = 0;
|
||||
snprintf(rnamebuf, sizeof rnamebuf, "%s", pw->pw_name);
|
||||
}
|
||||
else
|
||||
(void) snprintf(rnamebuf, sizeof rnamebuf, "Unknown UID %d",
|
||||
(int) RealUid);
|
||||
RunAsUserName = RealUserName = rnamebuf;
|
||||
|
||||
cfile = _PATH_SENDMAILCF;
|
||||
#if _FFR_GRAB_ALIASFILE_OPTION
|
||||
while ((ch = getopt(argc, argv, "C:f:")) != -1)
|
||||
#else
|
||||
while ((ch = getopt(argc, argv, "f:")) != -1)
|
||||
#endif
|
||||
{
|
||||
switch ((char)ch) {
|
||||
case 'C':
|
||||
@ -91,11 +104,7 @@ main(argc, argv)
|
||||
case '?':
|
||||
default:
|
||||
(void)fprintf(stderr,
|
||||
#if _FFR_GRAB_ALIASFILE_OPTION
|
||||
"usage: praliases [-C cffile] [-f aliasfile]\n");
|
||||
#else
|
||||
"usage: praliases [-f aliasfile]\n");
|
||||
#endif
|
||||
"usage: praliases [-C cffile] [-f aliasfile]\n");
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
}
|
||||
@ -110,8 +119,8 @@ main(argc, argv)
|
||||
|
||||
if ((cfp = fopen(cfile, "r")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "praliases: ");
|
||||
perror(cfile);
|
||||
fprintf(stderr, "praliases: %s: %s\n",
|
||||
cfile, errstring(errno));
|
||||
exit(EX_NOINPUT);
|
||||
}
|
||||
|
||||
@ -119,6 +128,10 @@ main(argc, argv)
|
||||
{
|
||||
register char *b, *p;
|
||||
|
||||
b = strchr(buf, '\n');
|
||||
if (b != NULL)
|
||||
*b = '\0';
|
||||
|
||||
b = buf;
|
||||
switch (*b++)
|
||||
{
|
||||
@ -140,15 +153,15 @@ main(argc, argv)
|
||||
}
|
||||
|
||||
/* this is the A or AliasFile option -- save it */
|
||||
if (strlen(b) >= sizeof afilebuf)
|
||||
if (strlcpy(afilebuf, b, sizeof afilebuf) >=
|
||||
sizeof afilebuf)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"AliasFile filename too long: %.30s...\n",
|
||||
"praliases: AliasFile filename too long: %.30s\n",
|
||||
b);
|
||||
(void) fclose(cfp);
|
||||
exit(EX_CONFIG);
|
||||
}
|
||||
strcpy(afilebuf, b);
|
||||
b = afilebuf;
|
||||
|
||||
for (p = b; p != NULL; )
|
||||
@ -160,12 +173,50 @@ main(argc, argv)
|
||||
b = p;
|
||||
|
||||
p = strpbrk(p, " ,/");
|
||||
|
||||
/* find end of spec */
|
||||
if (p != NULL)
|
||||
p = strpbrk(p, ",\n");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
{
|
||||
bool quoted = FALSE;
|
||||
|
||||
for (; *p != '\0'; p++)
|
||||
{
|
||||
/*
|
||||
** Don't break into a quoted
|
||||
** string.
|
||||
*/
|
||||
|
||||
if (*p == '"')
|
||||
quoted = !quoted;
|
||||
else if (*p == ',' && !quoted)
|
||||
break;
|
||||
}
|
||||
|
||||
/* No more alias specs follow */
|
||||
if (*p == '\0')
|
||||
{
|
||||
/* chop trailing whitespace */
|
||||
while (isascii(*p) &&
|
||||
isspace(*p) &&
|
||||
p > b)
|
||||
p--;
|
||||
*p = '\0';
|
||||
p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
char *e = p - 1;
|
||||
|
||||
/* chop trailing whitespace */
|
||||
while (isascii(*e) &&
|
||||
isspace(*e) &&
|
||||
e > b)
|
||||
e--;
|
||||
*++e = '\0';
|
||||
*p++ = '\0';
|
||||
}
|
||||
praliases(b, argc, argv);
|
||||
}
|
||||
|
||||
@ -175,196 +226,192 @@ main(argc, argv)
|
||||
}
|
||||
(void) fclose(cfp);
|
||||
exit(EX_OK);
|
||||
/* NOTREACHED */
|
||||
return EX_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
praliases(filename, argc, argv)
|
||||
char *filename;
|
||||
int argc;
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
#ifdef NEWDB
|
||||
DB *db;
|
||||
DBT newdbkey, newdbcontent;
|
||||
char buf[MAXNAME];
|
||||
#endif
|
||||
char *class;
|
||||
int result;
|
||||
char *colon;
|
||||
char *db_name;
|
||||
char *db_type;
|
||||
SMDB_DATABASE *database = NULL;
|
||||
SMDB_CURSOR *cursor = NULL;
|
||||
SMDB_DBENT db_key, db_value;
|
||||
SMDB_DBPARAMS params;
|
||||
SMDB_USER_INFO user_info;
|
||||
|
||||
class = strchr(filename, ':');
|
||||
if (class != NULL)
|
||||
colon = strchr(filename, ':');
|
||||
if (colon == NULL)
|
||||
{
|
||||
if (strncasecmp(filename, "dbm:", 4) == 0)
|
||||
{
|
||||
#ifdef NDBM
|
||||
praliases_dbm(class + 1, argc, argv);
|
||||
return;
|
||||
#else
|
||||
fprintf(stderr, "class dbm not available\n");
|
||||
exit(EX_DATAERR);
|
||||
#endif
|
||||
}
|
||||
filename = class + 1;
|
||||
}
|
||||
#ifdef NEWDB
|
||||
if (strlen(filename) + 4 >= sizeof buf)
|
||||
{
|
||||
fprintf(stderr, "Alias filename too long: %.30s...\n", filename);
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
(void) strcpy(buf, filename);
|
||||
(void) strcat(buf, ".db");
|
||||
# if DB_VERSION_MAJOR < 2
|
||||
db = dbopen(buf, O_RDONLY, 0444, DB_HASH, NULL);
|
||||
# else
|
||||
db = NULL;
|
||||
errno = db_open(buf, DB_HASH, DB_RDONLY, 0444, NULL, NULL, &db);
|
||||
# endif
|
||||
if (db != NULL)
|
||||
{
|
||||
if (!argc)
|
||||
{
|
||||
# if DB_VERSION_MAJOR > 1
|
||||
DBC *dbc;
|
||||
# endif
|
||||
bzero(&newdbkey, sizeof newdbkey);
|
||||
bzero(&newdbcontent, sizeof newdbcontent);
|
||||
|
||||
# if DB_VERSION_MAJOR < 2
|
||||
while(!db->seq(db, &newdbkey, &newdbcontent, R_NEXT))
|
||||
# else
|
||||
# if DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >=6
|
||||
if ((errno = db->cursor(db, NULL, &dbc, 0)) == 0)
|
||||
# else
|
||||
if ((errno = db->cursor(db, NULL, &dbc)) == 0)
|
||||
# endif
|
||||
{
|
||||
while ((errno = dbc->c_get(dbc, &newdbkey,
|
||||
&newdbcontent,
|
||||
DB_NEXT)) == 0)
|
||||
# endif
|
||||
printf("%.*s:%.*s\n",
|
||||
(int) newdbkey.size,
|
||||
(char *) newdbkey.data,
|
||||
(int) newdbcontent.size,
|
||||
(char *) newdbcontent.data);
|
||||
# if DB_VERSION_MAJOR > 1
|
||||
(void) dbc->c_close(dbc);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"praliases: %s: Could not set cursor: %s\n",
|
||||
buf, strerror(errno));
|
||||
errno = db->close(db, 0);
|
||||
exit(EX_DATAERR);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
else for (; *argv; ++argv)
|
||||
{
|
||||
bzero(&newdbkey, sizeof newdbkey);
|
||||
bzero(&newdbcontent, sizeof newdbcontent);
|
||||
newdbkey.data = *argv;
|
||||
newdbkey.size = strlen(*argv) + 1;
|
||||
# if DB_VERSION_MAJOR < 2
|
||||
if (!db->get(db, &newdbkey, &newdbcontent, 0))
|
||||
# else
|
||||
if ((errno = db->get(db, NULL, &newdbkey,
|
||||
&newdbcontent, 0)) == 0)
|
||||
# endif
|
||||
printf("%s:%.*s\n", (char *) newdbkey.data,
|
||||
(int) newdbcontent.size,
|
||||
(char *) newdbcontent.data);
|
||||
else
|
||||
printf("%s: No such key\n",
|
||||
(char *) newdbkey.data);
|
||||
}
|
||||
# if DB_VERSION_MAJOR < 2
|
||||
(void)db->close(db);
|
||||
# else
|
||||
errno = db->close(db, 0);
|
||||
# endif
|
||||
db_name = filename;
|
||||
db_type = SMDB_TYPE_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
#ifdef NDBM
|
||||
praliases_dbm(filename, argc, argv);
|
||||
#endif
|
||||
#ifdef NEWDB
|
||||
*colon = '\0';
|
||||
db_name = colon + 1;
|
||||
db_type = filename;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NDBM
|
||||
static void
|
||||
praliases_dbm(filename, argc, argv)
|
||||
char *filename;
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
DBM *dbp;
|
||||
datum content, key;
|
||||
|
||||
if ((dbp = dbm_open(filename, O_RDONLY, 0)) == NULL)
|
||||
/* clean off arguments */
|
||||
for (;;)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"praliases: %s: %s\n", filename, strerror(errno));
|
||||
exit(EX_OSFILE);
|
||||
while (isascii(*db_name) && isspace(*db_name))
|
||||
db_name++;
|
||||
if (*db_name != '-')
|
||||
break;
|
||||
while (*db_name != '\0' &&
|
||||
!(isascii(*db_name) && isspace(*db_name)))
|
||||
db_name++;
|
||||
}
|
||||
if (!argc)
|
||||
|
||||
if (*db_name == '\0' || (db_type != NULL && *db_type == '\0'))
|
||||
{
|
||||
for (key = dbm_firstkey(dbp);
|
||||
key.dptr != NULL; key = dbm_nextkey(dbp))
|
||||
if (colon != NULL)
|
||||
*colon = ':';
|
||||
fprintf(stderr, "praliases: illegal alias specification: %s\n",
|
||||
filename);
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
memset(¶ms, '\0', sizeof params);
|
||||
params.smdbp_cache_size = 1024 * 1024;
|
||||
|
||||
user_info.smdbu_id = RunAsUid;
|
||||
user_info.smdbu_group_id = RunAsGid;
|
||||
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));
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
memset(&db_key, '\0', sizeof db_key);
|
||||
memset(&db_value, '\0', sizeof db_value);
|
||||
|
||||
result = database->smdb_cursor(database, &cursor, 0);
|
||||
if (result != SMDBE_OK)
|
||||
{
|
||||
content = dbm_fetch(dbp, key);
|
||||
(void)printf("%.*s:%.*s\n",
|
||||
(int) key.dsize, key.dptr,
|
||||
(int) content.dsize, content.dptr);
|
||||
fprintf(stderr, "praliases: %s: set cursor: %s\n",
|
||||
db_name, errstring(result));
|
||||
goto fatal;
|
||||
}
|
||||
|
||||
while ((result = cursor->smdbc_get(cursor, &db_key, &db_value,
|
||||
SMDB_CURSOR_GET_NEXT)) ==
|
||||
SMDBE_OK)
|
||||
{
|
||||
#if 0
|
||||
/* skip magic @:@ entry */
|
||||
if (db_key.data.size == 2 &&
|
||||
db_key.data.data[0] == '@' &&
|
||||
db_key.data.data[1] == '\0' &&
|
||||
db_value.data.size == 2 &&
|
||||
db_value.data.data[0] == '@' &&
|
||||
db_value.data.data[1] == '\0')
|
||||
continue;
|
||||
#endif /* 0 */
|
||||
|
||||
printf("%.*s:%.*s\n",
|
||||
(int) db_key.data.size,
|
||||
(char *) db_key.data.data,
|
||||
(int) db_value.data.size,
|
||||
(char *) db_value.data.data);
|
||||
}
|
||||
|
||||
if (result != SMDBE_OK && result != SMDBE_LAST_ENTRY)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"praliases: %s: get value at cursor: %s\n",
|
||||
db_name, errstring(result));
|
||||
goto fatal;
|
||||
}
|
||||
}
|
||||
else
|
||||
else for (; *argv != NULL; ++argv)
|
||||
{
|
||||
for (; *argv; ++argv)
|
||||
memset(&db_key, '\0', sizeof db_key);
|
||||
memset(&db_value, '\0', sizeof db_value);
|
||||
db_key.data.data = *argv;
|
||||
db_key.data.size = strlen(*argv) + 1;
|
||||
if (database->smdb_get(database, &db_key,
|
||||
&db_value, 0) == SMDBE_OK)
|
||||
{
|
||||
/*
|
||||
** Use the sendmail adaptive algorithm of trying
|
||||
** the key first without, then if needed with,
|
||||
** the terminating NULL byte.
|
||||
*/
|
||||
key.dptr = *argv;
|
||||
key.dsize = strlen(*argv);
|
||||
content = dbm_fetch(dbp, key);
|
||||
if (content.dptr == NULL)
|
||||
{
|
||||
key.dsize++;
|
||||
content = dbm_fetch(dbp, key);
|
||||
}
|
||||
if (content.dptr != NULL)
|
||||
(void)printf("%s:%.*s\n", key.dptr,
|
||||
(int) content.dsize, content.dptr);
|
||||
else
|
||||
(void)printf("%s: No such key\n", key.dptr);
|
||||
printf("%.*s:%.*s\n",
|
||||
(int) db_key.data.size,
|
||||
(char *) db_key.data.data,
|
||||
(int) db_value.data.size,
|
||||
(char *) db_value.data.data);
|
||||
}
|
||||
else
|
||||
printf("%s: No such key\n", (char *) db_key.data.data);
|
||||
}
|
||||
dbm_close(dbp);
|
||||
|
||||
fatal:
|
||||
if (cursor != NULL)
|
||||
(void) cursor->smdbc_close(cursor);
|
||||
if (database != NULL)
|
||||
(void) database->smdb_close(database);
|
||||
if (colon != NULL)
|
||||
*colon = ':';
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !HASSTRERROR
|
||||
|
||||
char *
|
||||
strerror(eno)
|
||||
int eno;
|
||||
/*VARARGS1*/
|
||||
void
|
||||
#ifdef __STDC__
|
||||
message(const char *msg, ...)
|
||||
#else /* __STDC__ */
|
||||
message(msg, va_alist)
|
||||
const char *msg;
|
||||
va_dcl
|
||||
#endif /* __STDC__ */
|
||||
{
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
static char ebuf[60];
|
||||
const char *m;
|
||||
VA_LOCAL_DECL
|
||||
|
||||
if (eno >= 0 && eno < sys_nerr)
|
||||
return sys_errlist[eno];
|
||||
(void) sprintf(ebuf, "Error %d", eno);
|
||||
return ebuf;
|
||||
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");
|
||||
}
|
||||
|
||||
#endif /* !HASSTRERROR */
|
||||
/*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");
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
* Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
@ -11,20 +12,24 @@
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1988, 1993\n\
|
||||
"@(#) Copyright (c) 1998-2000 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 /* not lint */
|
||||
#endif /* ! lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)rmail.c 8.18 (Berkeley) 10/23/1998";
|
||||
#endif /* not lint */
|
||||
static char id[] = "@(#)$Id: rmail.c,v 8.39.4.5 2000/07/18 05:55:29 gshapiro Exp $";
|
||||
#endif /* ! lint */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* RMAIL -- UUCP mail server.
|
||||
*
|
||||
* This program reads the >From ... remote from ... lines that UUCP is so
|
||||
* fond of and turns them into something reasonable. It then execs sendmail
|
||||
* with various options built from these lines.
|
||||
* with various options built from these lines.
|
||||
*
|
||||
* The expected syntax is:
|
||||
*
|
||||
@ -43,6 +48,8 @@ static char sccsid[] = "@(#)rmail.c 8.18 (Berkeley) 10/23/1998";
|
||||
* The err(3) routine is included here deliberately to make this code
|
||||
* a bit more portable.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
@ -52,66 +59,74 @@ static char sccsid[] = "@(#)rmail.c 8.18 (Berkeley) 10/23/1998";
|
||||
#ifdef BSD4_4
|
||||
# define FORK vfork
|
||||
# include <paths.h>
|
||||
#else
|
||||
#else /* BSD4_4 */
|
||||
# define FORK fork
|
||||
# ifndef _PATH_SENDMAIL
|
||||
# define _PATH_SENDMAIL "/usr/lib/sendmail"
|
||||
# endif
|
||||
#endif
|
||||
# endif /* ! _PATH_SENDMAIL */
|
||||
#endif /* BSD4_4 */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifdef EX_OK
|
||||
# undef EX_OK /* unistd.h may have another use for this */
|
||||
#endif
|
||||
#endif /* EX_OK */
|
||||
#include <sysexits.h>
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) ((a) < (b) ? (b) : (a))
|
||||
#endif
|
||||
#endif /* ! MAX */
|
||||
|
||||
#ifndef __P
|
||||
# ifdef __STDC__
|
||||
# define __P(protos) protos
|
||||
# else
|
||||
# else /* __STDC__ */
|
||||
# define __P(protos) ()
|
||||
# define const
|
||||
# endif
|
||||
#endif
|
||||
# endif /* __STDC__ */
|
||||
#endif /* ! __P */
|
||||
|
||||
#if defined(BSD4_4) || defined(linux) || SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206)
|
||||
#ifndef STDIN_FILENO
|
||||
# define STDIN_FILENO 0
|
||||
#endif /* ! STDIN_FILENO */
|
||||
|
||||
#if defined(BSD4_4) || defined(linux) || SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) || _AIX4 >= 40300
|
||||
# define HASSNPRINTF 1
|
||||
#endif
|
||||
|
||||
#if defined(IRIX64) || defined(IRIX5) || defined(IRIX6) || \
|
||||
defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__)
|
||||
# ifndef HASSTRERROR
|
||||
# define HASSTRERROR 1 /* has strerror(3) */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HASSTRERROR
|
||||
extern char *strerror __P((int));
|
||||
#endif
|
||||
#endif /* defined(BSD4_4) || defined(linux) || SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) || _AIX4 >= 40300 */
|
||||
|
||||
#if defined(sun) && !defined(BSD) && !defined(SOLARIS) && !defined(__svr4__) && !defined(__SVR4)
|
||||
# define memmove(d, s, l) (bcopy((s), (d), (l)))
|
||||
#endif
|
||||
# define memmove(d, s, l) (bcopy((s), (d), (l)))
|
||||
#endif /* defined(sun) && !defined(BSD) && !defined(SOLARIS) && !defined(__svr4__) && !defined(__SVR4) */
|
||||
|
||||
#if !HASSNPRINTF
|
||||
extern int snprintf __P((char *, size_t, const char *, ...));
|
||||
#endif /* !HASSNPRINTF */
|
||||
|
||||
u_char tTdvect[100];
|
||||
#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) */
|
||||
|
||||
void err __P((int, const char *, ...));
|
||||
void usage __P((void));
|
||||
char *xalloc __P((int));
|
||||
#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"
|
||||
|
||||
static void err __P((int, const char *, ...));
|
||||
static void usage __P((void));
|
||||
static char *xalloc __P((int));
|
||||
|
||||
#define newstr(s) strcpy(xalloc(strlen(s) + 1), s)
|
||||
|
||||
char *
|
||||
static char *
|
||||
xalloc(sz)
|
||||
register int sz;
|
||||
{
|
||||
@ -132,45 +147,49 @@ main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int errno, optind;
|
||||
FILE *fp;
|
||||
struct stat sb;
|
||||
int ch, debug, i, pdes[2], pid, status;
|
||||
size_t fplen = 0, fptlen = 0, len;
|
||||
off_t offset;
|
||||
int ch, debug, i, pdes[2], pid, status;
|
||||
FILE *fp;
|
||||
char *addrp = NULL, *domain, *p, *t;
|
||||
char *from_path, *from_sys, *from_user;
|
||||
char *args[100], buf[2048], lbuf[2048];
|
||||
struct stat sb;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
debug = 0;
|
||||
domain = "UUCP"; /* Default "domain". */
|
||||
while ((ch = getopt(argc, argv, "D:T")) != -1)
|
||||
switch (ch) {
|
||||
case 'T':
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case 'T':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'D':
|
||||
|
||||
case 'D':
|
||||
domain = optarg;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
fplen = fptlen = 0;
|
||||
addrp = "";
|
||||
from_path = from_sys = from_user = NULL;
|
||||
for (offset = 0;;) {
|
||||
|
||||
for (offset = 0; ; )
|
||||
{
|
||||
/* Get and nul-terminate the line. */
|
||||
if (fgets(lbuf, sizeof(lbuf), stdin) == NULL)
|
||||
exit (EX_DATAERR);
|
||||
exit(EX_DATAERR);
|
||||
if ((p = strchr(lbuf, '\n')) == NULL)
|
||||
err(EX_DATAERR, "line too long");
|
||||
*p = '\0';
|
||||
@ -183,32 +202,40 @@ main(argc, argv)
|
||||
else if (offset == 0)
|
||||
err(EX_DATAERR,
|
||||
"missing or empty From line: %s", lbuf);
|
||||
else {
|
||||
else
|
||||
{
|
||||
*p = '\n';
|
||||
break;
|
||||
}
|
||||
|
||||
if (*addrp == '\0')
|
||||
if (addrp == NULL || *addrp == '\0')
|
||||
err(EX_DATAERR, "corrupted From line: %s", lbuf);
|
||||
|
||||
/* Use the "remote from" if it exists. */
|
||||
for (p = addrp; (p = strchr(p + 1, 'r')) != NULL;)
|
||||
if (!strncmp(p, "remote from ", 12)) {
|
||||
for (t = p += 12;
|
||||
*t && !(isascii(*t) && isspace(*t)); ++t);
|
||||
for (p = addrp; (p = strchr(p + 1, 'r')) != NULL; )
|
||||
{
|
||||
if (!strncmp(p, "remote from ", 12))
|
||||
{
|
||||
for (t = p += 12; *t != '\0'; ++t)
|
||||
{
|
||||
if (isascii(*t) && isspace(*t))
|
||||
break;
|
||||
}
|
||||
*t = '\0';
|
||||
if (debug)
|
||||
(void)fprintf(stderr,
|
||||
"remote from: %s\n", p);
|
||||
fprintf(stderr, "remote from: %s\n", p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Else use the string up to the last bang. */
|
||||
if (p == NULL) {
|
||||
if (p == NULL)
|
||||
{
|
||||
if (*addrp == '!')
|
||||
err(EX_DATAERR,
|
||||
"bang starts address: %s", addrp);
|
||||
else if ((t = strrchr(addrp, '!')) != NULL) {
|
||||
err(EX_DATAERR, "bang starts address: %s",
|
||||
addrp);
|
||||
else if ((t = strrchr(addrp, '!')) != NULL)
|
||||
{
|
||||
*t = '\0';
|
||||
p = addrp;
|
||||
addrp = t + 1;
|
||||
@ -216,34 +243,43 @@ main(argc, argv)
|
||||
err(EX_DATAERR,
|
||||
"corrupted From line: %s", lbuf);
|
||||
if (debug)
|
||||
(void)fprintf(stderr, "bang: %s\n", p);
|
||||
fprintf(stderr, "bang: %s\n", p);
|
||||
}
|
||||
}
|
||||
|
||||
/* 'p' now points to any system string from this line. */
|
||||
if (p != NULL) {
|
||||
if (p != NULL)
|
||||
{
|
||||
/* Nul terminate it as necessary. */
|
||||
for (t = p; *t && !(isascii(*t) && isspace(*t)); ++t);
|
||||
for (t = p; *t != '\0'; ++t)
|
||||
{
|
||||
if (isascii(*t) && isspace(*t))
|
||||
break;
|
||||
}
|
||||
*t = '\0';
|
||||
|
||||
/* If the first system, copy to the from_sys string. */
|
||||
if (from_sys == NULL) {
|
||||
if (from_sys == NULL)
|
||||
{
|
||||
from_sys = newstr(p);
|
||||
if (debug)
|
||||
(void)fprintf(stderr,
|
||||
"from_sys: %s\n", from_sys);
|
||||
fprintf(stderr, "from_sys: %s\n",
|
||||
from_sys);
|
||||
}
|
||||
|
||||
/* Concatenate to the path string. */
|
||||
len = t - p;
|
||||
if (from_path == NULL) {
|
||||
if (from_path == NULL)
|
||||
{
|
||||
fplen = 0;
|
||||
if ((from_path = malloc(fptlen = 256)) == NULL)
|
||||
err(EX_TEMPFAIL, NULL);
|
||||
}
|
||||
if (fplen + len + 2 > fptlen) {
|
||||
if (fplen + len + 2 > fptlen)
|
||||
{
|
||||
fptlen += MAX(fplen + len + 2, 256);
|
||||
if ((from_path =
|
||||
realloc(from_path, fptlen)) == NULL)
|
||||
if ((from_path = realloc(from_path,
|
||||
fptlen)) == NULL)
|
||||
err(EX_TEMPFAIL, NULL);
|
||||
}
|
||||
memmove(from_path + fplen, p, len);
|
||||
@ -253,7 +289,11 @@ main(argc, argv)
|
||||
}
|
||||
|
||||
/* Save off from user's address; the last one wins. */
|
||||
for (p = addrp; *p && !(isascii(*p) && isspace(*p)); ++p);
|
||||
for (p = addrp; *p != '\0'; ++p)
|
||||
{
|
||||
if (isascii(*p) && isspace(*p))
|
||||
break;
|
||||
}
|
||||
*p = '\0';
|
||||
if (*addrp == '\0')
|
||||
addrp = "<>";
|
||||
@ -261,11 +301,11 @@ main(argc, argv)
|
||||
free(from_user);
|
||||
from_user = newstr(addrp);
|
||||
|
||||
if (debug) {
|
||||
if (debug)
|
||||
{
|
||||
if (from_path != NULL)
|
||||
(void)fprintf(stderr,
|
||||
"from_path: %s\n", from_path);
|
||||
(void)fprintf(stderr, "from_user: %s\n", from_user);
|
||||
fprintf(stderr, "from_path: %s\n", from_path);
|
||||
fprintf(stderr, "from_user: %s\n", from_user);
|
||||
}
|
||||
|
||||
if (offset != -1)
|
||||
@ -284,86 +324,99 @@ main(argc, argv)
|
||||
|
||||
/* set from system and protocol used */
|
||||
if (from_sys == NULL)
|
||||
(void)snprintf(buf, sizeof(buf), "-p%s", domain);
|
||||
snprintf(buf, sizeof(buf), "-p%s", domain);
|
||||
else if (strchr(from_sys, '.') == NULL)
|
||||
(void)snprintf(buf, sizeof(buf), "-p%s:%s.%s",
|
||||
snprintf(buf, sizeof(buf), "-p%s:%s.%s",
|
||||
domain, from_sys, domain);
|
||||
else
|
||||
(void)snprintf(buf, sizeof(buf), "-p%s:%s", domain, from_sys);
|
||||
snprintf(buf, sizeof(buf), "-p%s:%s", domain, from_sys);
|
||||
args[i++] = newstr(buf);
|
||||
|
||||
/* Set name of ``from'' person. */
|
||||
(void)snprintf(buf, sizeof(buf), "-f%s%s",
|
||||
from_path ? from_path : "", from_user);
|
||||
/* Set name of ``from'' person. */
|
||||
snprintf(buf, sizeof(buf), "-f%s%s",
|
||||
from_path ? from_path : "", from_user);
|
||||
args[i++] = newstr(buf);
|
||||
|
||||
/*
|
||||
* Don't copy arguments beginning with - as they will be
|
||||
* passed to sendmail and could be interpreted as flags.
|
||||
* To prevent confusion of sendmail wrap < and > around
|
||||
* the address (helps to pass addrs like @gw1,@gw2:aa@bb)
|
||||
*/
|
||||
while (*argv) {
|
||||
** Don't copy arguments beginning with - as they will be
|
||||
** passed to sendmail and could be interpreted as flags.
|
||||
** To prevent confusion of sendmail wrap < and > around
|
||||
** the address (helps to pass addrs like @gw1,@gw2:aa@bb)
|
||||
*/
|
||||
|
||||
while (*argv)
|
||||
{
|
||||
if (**argv == '-')
|
||||
err(EX_USAGE, "dash precedes argument: %s", *argv);
|
||||
|
||||
if (strchr(*argv, ',') == NULL || strchr(*argv, '<') != NULL)
|
||||
args[i++] = *argv;
|
||||
else {
|
||||
if ((args[i] = malloc(strlen(*argv) + 3)) == NULL)
|
||||
else
|
||||
{
|
||||
len = strlen(*argv) + 3;
|
||||
if ((args[i] = malloc(len)) == NULL)
|
||||
err(EX_TEMPFAIL, "Cannot malloc");
|
||||
sprintf (args [i++], "<%s>", *argv);
|
||||
snprintf(args[i++], len, "<%s>", *argv);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
args[i] = 0;
|
||||
|
||||
if (debug) {
|
||||
(void)fprintf(stderr, "Sendmail arguments:\n");
|
||||
if (debug)
|
||||
{
|
||||
fprintf(stderr, "Sendmail arguments:\n");
|
||||
for (i = 0; args[i]; i++)
|
||||
(void)fprintf(stderr, "\t%s\n", args[i]);
|
||||
fprintf(stderr, "\t%s\n", args[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* If called with a regular file as standard input, seek to the right
|
||||
* position in the file and just exec sendmail. Could probably skip
|
||||
* skip the stat, but it's not unreasonable to believe that a failed
|
||||
* seek will cause future reads to fail.
|
||||
*/
|
||||
if (!fstat(STDIN_FILENO, &sb) && S_ISREG(sb.st_mode)) {
|
||||
** If called with a regular file as standard input, seek to the right
|
||||
** position in the file and just exec sendmail. Could probably skip
|
||||
** skip the stat, but it's not unreasonable to believe that a failed
|
||||
** seek will cause future reads to fail.
|
||||
*/
|
||||
|
||||
if (!fstat(STDIN_FILENO, &sb) && S_ISREG(sb.st_mode))
|
||||
{
|
||||
if (lseek(STDIN_FILENO, offset, SEEK_SET) != offset)
|
||||
err(EX_TEMPFAIL, "stdin seek");
|
||||
execv(_PATH_SENDMAIL, args);
|
||||
(void) execv(_PATH_SENDMAIL, args);
|
||||
err(EX_OSERR, "%s", _PATH_SENDMAIL);
|
||||
}
|
||||
|
||||
if (pipe(pdes) < 0)
|
||||
err(EX_OSERR, NULL);
|
||||
|
||||
switch (pid = FORK()) {
|
||||
case -1: /* Err. */
|
||||
switch (pid = FORK())
|
||||
{
|
||||
case -1: /* Err. */
|
||||
err(EX_OSERR, NULL);
|
||||
case 0: /* Child. */
|
||||
if (pdes[0] != STDIN_FILENO) {
|
||||
(void)dup2(pdes[0], STDIN_FILENO);
|
||||
(void)close(pdes[0]);
|
||||
/* NOTREACHED */
|
||||
|
||||
case 0: /* Child. */
|
||||
if (pdes[0] != STDIN_FILENO)
|
||||
{
|
||||
(void) dup2(pdes[0], STDIN_FILENO);
|
||||
(void) close(pdes[0]);
|
||||
}
|
||||
(void)close(pdes[1]);
|
||||
execv(_PATH_SENDMAIL, args);
|
||||
(void) close(pdes[1]);
|
||||
(void) execv(_PATH_SENDMAIL, args);
|
||||
_exit(127);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if ((fp = fdopen(pdes[1], "w")) == NULL)
|
||||
err(EX_OSERR, NULL);
|
||||
(void)close(pdes[0]);
|
||||
(void) close(pdes[0]);
|
||||
|
||||
/* Copy the file down the pipe. */
|
||||
do {
|
||||
(void)fprintf(fp, "%s", lbuf);
|
||||
do
|
||||
{
|
||||
(void) fprintf(fp, "%s", lbuf);
|
||||
} while (fgets(lbuf, sizeof(lbuf), stdin) != NULL);
|
||||
|
||||
if (ferror(stdin))
|
||||
err(EX_TEMPFAIL, "stdin: %s", strerror(errno));
|
||||
err(EX_TEMPFAIL, "stdin: %s", errstring(errno));
|
||||
|
||||
if (fclose(fp))
|
||||
err(EX_OSERR, NULL);
|
||||
@ -372,65 +425,48 @@ main(argc, argv)
|
||||
err(EX_OSERR, "%s", _PATH_SENDMAIL);
|
||||
|
||||
if (!WIFEXITED(status))
|
||||
err(EX_OSERR,
|
||||
"%s: did not terminate normally", _PATH_SENDMAIL);
|
||||
err(EX_OSERR, "%s: did not terminate normally", _PATH_SENDMAIL);
|
||||
|
||||
if (WEXITSTATUS(status))
|
||||
err(status, "%s: terminated with %d (non-zero) status",
|
||||
_PATH_SENDMAIL, WEXITSTATUS(status));
|
||||
exit(EX_OK);
|
||||
/* NOTREACHED */
|
||||
return EX_OK;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: rmail [-T] [-D domain] user ...\n");
|
||||
(void) fprintf(stderr, "usage: rmail [-T] [-D domain] user ...\n");
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
# include <stdarg.h>
|
||||
#else /* __STDC__ */
|
||||
# include <varargs.h>
|
||||
#endif /* __STDC__ */
|
||||
|
||||
void
|
||||
static void
|
||||
#ifdef __STDC__
|
||||
err(int eval, const char *fmt, ...)
|
||||
#else
|
||||
#else /* __STDC__ */
|
||||
err(eval, fmt, va_alist)
|
||||
int eval;
|
||||
const char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
#endif /* __STDC__ */
|
||||
{
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
#ifdef __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
#else /* __STDC__ */
|
||||
va_start(ap);
|
||||
#endif
|
||||
(void)fprintf(stderr, "rmail: ");
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
#endif /* __STDC__ */
|
||||
(void) fprintf(stderr, "rmail: ");
|
||||
(void) vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
(void)fprintf(stderr, "\n");
|
||||
(void) fprintf(stderr, "\n");
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
#if !HASSTRERROR
|
||||
|
||||
char *
|
||||
strerror(eno)
|
||||
int eno;
|
||||
{
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
static char ebuf[60];
|
||||
|
||||
if (eno >= 0 && eno < sys_nerr)
|
||||
return sys_errlist[eno];
|
||||
(void) sprintf(ebuf, "Error %d", eno);
|
||||
return ebuf;
|
||||
}
|
||||
|
||||
#endif /* !HASSTRERROR */
|
||||
|
@ -1,4 +1,5 @@
|
||||
.\" Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
.\" Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1993 Eric P. Allman. All rights reserved.
|
||||
.\" Copyright (c) 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -8,7 +9,9 @@
|
||||
.\" the sendmail distribution.
|
||||
.\"
|
||||
.\"
|
||||
.\" @(#)smrsh.8 8.7 (Berkeley) 5/19/1998
|
||||
.\" $Id: smrsh.8,v 8.11 1999/06/09 16:51:07 ca Exp $
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.TH SMRSH 8 11/02/93
|
||||
.SH NAME
|
||||
@ -38,11 +41,14 @@ Briefly,
|
||||
.I smrsh
|
||||
limits programs to be in the directory
|
||||
/usr/libexec/sm.bin,
|
||||
allowing the system administrator to choose the set of acceptable commands.
|
||||
allowing the system administrator to choose the set of acceptable commands,
|
||||
and to the shell builtin commands ``exec'', ``exit'', and ``echo''.
|
||||
It also rejects any commands with the characters
|
||||
`\`', `<', `>', `|', `;', `&', `$', `(', `)', `\er' (carriage return),
|
||||
`\`', `<', `>', `;', `$', `(', `)', `\er' (carriage return),
|
||||
or `\en' (newline)
|
||||
on the command line to prevent ``end run'' attacks.
|
||||
It allows ``||'' and ``&&'' to enable commands like:
|
||||
``"|exec /usr/local/bin/procmail -f- /etc/procmailrcs/user || exit 75"''
|
||||
.PP
|
||||
Initial pathnames on programs are stripped,
|
||||
so forwarding to ``/usr/bin/vacation'',
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
* Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1993 Eric P. Allman. All rights reserved.
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -11,8 +12,19 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)smrsh.c 8.11 (Berkeley) 5/19/1998";
|
||||
#endif /* not lint */
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1998, 1999 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 */
|
||||
|
||||
#ifndef lint
|
||||
static char id[] = "@(#)$Id: smrsh.c,v 8.31.4.4 2000/05/25 21:44:29 gshapiro Exp $";
|
||||
#endif /* ! lint */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
** SMRSH -- sendmail restricted shell
|
||||
@ -32,12 +44,12 @@ static char sccsid[] = "@(#)smrsh.c 8.11 (Berkeley) 5/19/1998";
|
||||
** "/usr/bin/vacation" will continue to work.
|
||||
**
|
||||
** The following characters are completely illegal:
|
||||
** < > | ^ ; & $ ` ( ) \n \r
|
||||
** < > ^ & ` ( ) \n \r
|
||||
** The following characters are sometimes illegal:
|
||||
** | &
|
||||
** This is more restrictive than strictly necessary.
|
||||
**
|
||||
** To use this, edit /etc/sendmail.cf, search for ^Mprog, and
|
||||
** change P=/bin/sh to P=/usr/libexec/smrsh, where this compiled
|
||||
** binary is installed /usr/libexec/smrsh.
|
||||
** To use this, add FEATURE(`smrsh') to your .mc file.
|
||||
**
|
||||
** This can be used on any version of sendmail.
|
||||
**
|
||||
@ -49,17 +61,23 @@ static char sccsid[] = "@(#)smrsh.c 8.11 (Berkeley) 5/19/1998";
|
||||
#include <sys/file.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#ifdef EX_OK
|
||||
# undef EX_OK
|
||||
#endif
|
||||
#endif /* EX_OK */
|
||||
#include <sysexits.h>
|
||||
#include <syslog.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
#endif /* ! TRUE */
|
||||
|
||||
/* directory in which all commands must reside */
|
||||
#ifndef CMDDIR
|
||||
# define CMDDIR "/usr/libexec/sm.bin"
|
||||
#endif
|
||||
#endif /* ! CMDDIR */
|
||||
|
||||
/* characters disallowed in the shell "-c" argument */
|
||||
#define SPECIALS "<|>^();&`$\r\n"
|
||||
@ -67,7 +85,56 @@ static char sccsid[] = "@(#)smrsh.c 8.11 (Berkeley) 5/19/1998";
|
||||
/* default search path */
|
||||
#ifndef PATH
|
||||
# define PATH "/bin:/usr/bin"
|
||||
#endif
|
||||
#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;
|
||||
|
||||
/*
|
||||
** ADDCMD -- add a string to newcmdbuf, check for overflow
|
||||
**
|
||||
** Parameters:
|
||||
** s -- string to add
|
||||
** cmd -- it's a command: prepend CMDDIR/
|
||||
** len -- length of string to add
|
||||
**
|
||||
** Side Effects:
|
||||
** changes newcmdbuf or exits with a failure.
|
||||
**
|
||||
*/
|
||||
|
||||
void
|
||||
addcmd(s, cmd, len)
|
||||
char *s;
|
||||
int cmd;
|
||||
int len;
|
||||
{
|
||||
if (s == NULL || *s == '\0')
|
||||
return;
|
||||
|
||||
if (sizeof newcmdbuf - strlen(newcmdbuf) <=
|
||||
len + (cmd ? (strlen(CMDDIR) + 1) : 0))
|
||||
{
|
||||
fprintf(stderr, "%s: command too long: %s\n", prg, par);
|
||||
#ifndef DEBUG
|
||||
syslog(LOG_WARNING, "command too long: %.40s", par);
|
||||
#endif /* ! DEBUG */
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
if (cmd)
|
||||
{
|
||||
(void) strlcat(newcmdbuf, CMDDIR, sizeof newcmdbuf);
|
||||
(void) strlcat(newcmdbuf, "/", sizeof newcmdbuf);
|
||||
}
|
||||
(void) strlcat(newcmdbuf, s, sizeof newcmdbuf);
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -76,20 +143,26 @@ main(argc, argv)
|
||||
{
|
||||
register char *p;
|
||||
register char *q;
|
||||
register char *r;
|
||||
register char *cmd;
|
||||
int i;
|
||||
int isexec;
|
||||
int save_errno;
|
||||
char *newenv[2];
|
||||
char cmdbuf[1000];
|
||||
char pathbuf[1000];
|
||||
char specialbuf[32];
|
||||
|
||||
#ifndef LOG_MAIL
|
||||
#ifndef DEBUG
|
||||
# ifndef LOG_MAIL
|
||||
openlog("smrsh", 0);
|
||||
#else
|
||||
# else /* ! LOG_MAIL */
|
||||
openlog("smrsh", LOG_ODELAY|LOG_CONS, LOG_MAIL);
|
||||
#endif
|
||||
# endif /* ! LOG_MAIL */
|
||||
#endif /* ! DEBUG */
|
||||
|
||||
strcpy(pathbuf, "PATH=");
|
||||
strcat(pathbuf, PATH);
|
||||
(void) strlcpy(pathbuf, "PATH=", sizeof pathbuf);
|
||||
(void) strlcat(pathbuf, PATH, sizeof pathbuf);
|
||||
newenv[0] = pathbuf;
|
||||
newenv[1] = NULL;
|
||||
|
||||
@ -97,10 +170,15 @@ main(argc, argv)
|
||||
** Do basic argv usage checking
|
||||
*/
|
||||
|
||||
prg = argv[0];
|
||||
par = argv[2];
|
||||
|
||||
if (argc != 3 || strcmp(argv[1], "-c") != 0)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s -c command\n", argv[0]);
|
||||
fprintf(stderr, "Usage: %s -c command\n", prg);
|
||||
#ifndef DEBUG
|
||||
syslog(LOG_ERR, "usage");
|
||||
#endif /* ! DEBUG */
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
@ -111,103 +189,193 @@ main(argc, argv)
|
||||
** the address to 7 bits before checking.
|
||||
*/
|
||||
|
||||
strcpy(cmdbuf, SPECIALS);
|
||||
for (p = cmdbuf; *p != '\0'; p++)
|
||||
*p |= '\200';
|
||||
strcat(cmdbuf, SPECIALS);
|
||||
p = strpbrk(argv[2], cmdbuf);
|
||||
if (p != NULL)
|
||||
if (strlen(SPECIALS) * 2 >= sizeof specialbuf)
|
||||
{
|
||||
fprintf(stderr, "%s: cannot use %c in command\n",
|
||||
argv[0], *p);
|
||||
syslog(LOG_CRIT, "uid %d: attempt to use %c in command: %s",
|
||||
getuid(), *p, argv[2]);
|
||||
#ifndef DEBUG
|
||||
syslog(LOG_ERR, "too many specials: %.40s", SPECIALS);
|
||||
#endif /* ! DEBUG */
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
(void) strlcpy(specialbuf, SPECIALS, sizeof specialbuf);
|
||||
for (p = specialbuf; *p != '\0'; p++)
|
||||
*p |= '\200';
|
||||
(void) strlcat(specialbuf, SPECIALS, sizeof specialbuf);
|
||||
|
||||
/*
|
||||
** Do a quick sanity check on command line length.
|
||||
*/
|
||||
|
||||
i = strlen(argv[2]);
|
||||
if (i > (sizeof cmdbuf - sizeof CMDDIR - 2))
|
||||
i = strlen(par);
|
||||
if (i > (sizeof newcmdbuf - sizeof CMDDIR - 2))
|
||||
{
|
||||
fprintf(stderr, "%s: command too long: %s\n", argv[0], argv[2]);
|
||||
syslog(LOG_WARNING, "command too long: %.40s", argv[2]);
|
||||
fprintf(stderr, "%s: command too long: %s\n", prg, par);
|
||||
#ifndef DEBUG
|
||||
syslog(LOG_WARNING, "command too long: %.40s", par);
|
||||
#endif /* ! DEBUG */
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Strip off a leading pathname on the command name. For
|
||||
** example, change /usr/ucb/vacation to vacation.
|
||||
*/
|
||||
q = par;
|
||||
newcmdbuf[0] = '\0';
|
||||
isexec = FALSE;
|
||||
|
||||
/* strip leading spaces */
|
||||
for (q = argv[2]; *q != '\0' && isascii(*q) && isspace(*q); )
|
||||
q++;
|
||||
|
||||
/* find the end of the command name */
|
||||
p = strpbrk(q, " \t");
|
||||
if (p == NULL)
|
||||
cmd = &q[strlen(q)];
|
||||
else
|
||||
while (*q)
|
||||
{
|
||||
*p = '\0';
|
||||
cmd = p;
|
||||
}
|
||||
/*
|
||||
** Strip off a leading pathname on the command name. For
|
||||
** example, change /usr/ucb/vacation to vacation.
|
||||
*/
|
||||
|
||||
/* search backwards for last / (allow for 0200 bit) */
|
||||
while (cmd > q)
|
||||
{
|
||||
if ((*--cmd & 0177) == '/')
|
||||
/* strip leading spaces */
|
||||
while (*q != '\0' && isascii(*q) && isspace(*q))
|
||||
q++;
|
||||
if (*q == '\0')
|
||||
{
|
||||
cmd++;
|
||||
if (isexec)
|
||||
{
|
||||
fprintf(stderr, "%s: missing command to exec\n",
|
||||
prg);
|
||||
#ifndef DEBUG
|
||||
syslog(LOG_CRIT, "uid %d: missing command to exec", getuid());
|
||||
#endif /* ! DEBUG */
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* cmd now points at final component of path name */
|
||||
/* find the end of the command name */
|
||||
p = strpbrk(q, " \t");
|
||||
if (p == NULL)
|
||||
cmd = &q[strlen(q)];
|
||||
else
|
||||
{
|
||||
*p = '\0';
|
||||
cmd = p;
|
||||
}
|
||||
/* search backwards for last / (allow for 0200 bit) */
|
||||
while (cmd > q)
|
||||
{
|
||||
if ((*--cmd & 0177) == '/')
|
||||
{
|
||||
cmd++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* cmd now points at final component of path name */
|
||||
|
||||
/*
|
||||
** Check to see if the command name is legal.
|
||||
*/
|
||||
|
||||
(void) strcpy(cmdbuf, CMDDIR);
|
||||
(void) strcat(cmdbuf, "/");
|
||||
(void) strcat(cmdbuf, cmd);
|
||||
/* allow a few shell builtins */
|
||||
if (strcmp(q, "exec") == 0 && p != NULL)
|
||||
{
|
||||
addcmd("exec ", FALSE, strlen("exec "));
|
||||
/* test _next_ arg */
|
||||
q = ++p;
|
||||
isexec = TRUE;
|
||||
continue;
|
||||
}
|
||||
else if (strcmp(q, "exit") == 0 || strcmp(q, "echo") == 0)
|
||||
{
|
||||
addcmd(cmd, FALSE, strlen(cmd));
|
||||
/* test following chars */
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
** 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);
|
||||
#ifdef DEBUG
|
||||
printf("Trying %s\n", cmdbuf);
|
||||
#endif
|
||||
if (access(cmdbuf, X_OK) < 0)
|
||||
{
|
||||
/* oops.... crack attack possiblity */
|
||||
fprintf(stderr, "%s: %s not available for sendmail programs\n",
|
||||
argv[0], cmd);
|
||||
printf("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);
|
||||
if (p != NULL)
|
||||
*p = ' ';
|
||||
#ifndef DEBUG
|
||||
syslog(LOG_CRIT, "uid %d: attempt to use %s",
|
||||
getuid(), cmd);
|
||||
#endif /* ! DEBUG */
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Create the actual shell input.
|
||||
*/
|
||||
|
||||
addcmd(cmd, TRUE, strlen(cmd));
|
||||
}
|
||||
isexec = FALSE;
|
||||
|
||||
if (p != NULL)
|
||||
*p = ' ';
|
||||
syslog(LOG_CRIT, "uid %d: attempt to use %s", getuid(), cmd);
|
||||
else
|
||||
break;
|
||||
|
||||
r = strpbrk(p, specialbuf);
|
||||
if (r == NULL) {
|
||||
addcmd(p, FALSE, strlen(p));
|
||||
break;
|
||||
}
|
||||
#if ALLOWSEMI
|
||||
if (*r == ';') {
|
||||
addcmd(p, FALSE, r - p + 1);
|
||||
q = r + 1;
|
||||
continue;
|
||||
}
|
||||
#endif /* ALLOWSEMI */
|
||||
if ((*r == '&' && *(r + 1) == '&') ||
|
||||
(*r == '|' && *(r + 1) == '|'))
|
||||
{
|
||||
addcmd(p, FALSE, r - p + 2);
|
||||
q = r + 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%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);
|
||||
#endif /* ! DEBUG */
|
||||
exit(EX_UNAVAILABLE);
|
||||
} /* end of while *q */
|
||||
if (isexec)
|
||||
{
|
||||
fprintf(stderr, "%s: missing command to exec\n", prg);
|
||||
#ifndef DEBUG
|
||||
syslog(LOG_CRIT, "uid %d: missing command to exec", getuid());
|
||||
#endif /* ! DEBUG */
|
||||
exit(EX_UNAVAILABLE);
|
||||
}
|
||||
if (p != NULL)
|
||||
*p = ' ';
|
||||
|
||||
/*
|
||||
** Create the actual shell input.
|
||||
*/
|
||||
|
||||
strcpy(cmdbuf, CMDDIR);
|
||||
strcat(cmdbuf, "/");
|
||||
strcat(cmdbuf, cmd);
|
||||
/* make sure we created something */
|
||||
if (newcmdbuf[0] == '\0')
|
||||
{
|
||||
fprintf(stderr, "Usage: %s -c command\n", prg);
|
||||
#ifndef DEBUG
|
||||
syslog(LOG_ERR, "usage");
|
||||
#endif /* ! DEBUG */
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Now invoke the shell
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("%s\n", cmdbuf);
|
||||
#endif
|
||||
execle("/bin/sh", "/bin/sh", "-c", cmdbuf, NULL, newenv);
|
||||
printf("%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");
|
||||
#endif /* ! DEBUG */
|
||||
errno = save_errno;
|
||||
perror("/bin/sh");
|
||||
exit(EX_OSFILE);
|
||||
/* NOTREACHED */
|
||||
return EX_OSFILE;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
.\" Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
.\" Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1983, 1997 Eric P. Allman. All rights reserved.
|
||||
.\" Copyright (c) 1985, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -8,78 +9,114 @@
|
||||
.\" the sendmail distribution.
|
||||
.\"
|
||||
.\"
|
||||
.\" @(#)aliases.5 8.8 (Berkeley) 5/19/1998
|
||||
.\" $Id: aliases.5,v 8.15.4.1 2000/07/18 07:23:02 gshapiro Exp $
|
||||
.\"
|
||||
.Dd May 19, 1998
|
||||
.Dt ALIASES 5
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm aliases
|
||||
.Nd aliases file for sendmail
|
||||
.Sh SYNOPSIS
|
||||
.Nm aliases
|
||||
.Sh DESCRIPTION
|
||||
This file describes user
|
||||
.Tn ID
|
||||
aliases used by
|
||||
.Pa /usr/sbin/sendmail .
|
||||
The file resides in
|
||||
.Pa /etc
|
||||
and
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.TH ALIASES 5 "$Date: 2000/07/18 07:23:02 $"
|
||||
.SH NAME
|
||||
.B aliases
|
||||
\- aliases file for sendmail
|
||||
.SH SYNOPSIS
|
||||
.B aliases
|
||||
.SH DESCRIPTION
|
||||
This file describes user
|
||||
ID
|
||||
aliases used by
|
||||
sendmail.
|
||||
The file resides in
|
||||
/etc/mail
|
||||
and
|
||||
is formatted as a series of lines of the form
|
||||
.Bd -filled -offset indent
|
||||
name: name_1, name_2, name_3, . . .
|
||||
.Ed
|
||||
.Pp
|
||||
.IP
|
||||
name: addr_1, addr_2, addr_3, . . .
|
||||
.PP
|
||||
The
|
||||
.Em name
|
||||
.I name
|
||||
is the name to alias, and the
|
||||
.Em name_n
|
||||
are the aliases for that name.
|
||||
Lines beginning with white space are continuation lines.
|
||||
Lines beginning with
|
||||
.Ql #
|
||||
.I addr_n
|
||||
are the aliases for that name.
|
||||
.I addr_n
|
||||
can be another alias, a local username, a local filename,
|
||||
a command,
|
||||
an include file,
|
||||
or an external address.
|
||||
.TP
|
||||
.B Local Username
|
||||
username
|
||||
.IP
|
||||
The username must be available via getpwnam(3).
|
||||
.TP
|
||||
.B Local Filename
|
||||
/path/name
|
||||
.IP
|
||||
Messages are appended to the file specified by the full pathname
|
||||
(starting with a slash (/))
|
||||
.TP
|
||||
.B Command
|
||||
|command
|
||||
.IP
|
||||
A command starts with a pipe symbol (|),
|
||||
it receives messages via standard input.
|
||||
.TP
|
||||
.B Include File
|
||||
:include: /path/name
|
||||
.IP
|
||||
The aliases in pathname are added to the aliases for
|
||||
.I name.
|
||||
.TP
|
||||
.B E-Mail Address
|
||||
user@domain
|
||||
.IP
|
||||
An e-mail address in RFC 822 format.
|
||||
.PP
|
||||
Lines beginning with white space are continuation lines.
|
||||
Another way to continue lines is by placing a backslash
|
||||
directly before a newline.
|
||||
Lines beginning with
|
||||
#
|
||||
are comments.
|
||||
.Pp
|
||||
Aliasing occurs only on local names.
|
||||
.PP
|
||||
Aliasing occurs only on local names.
|
||||
Loops can not occur, since no message will be sent to any person more than once.
|
||||
.Pp
|
||||
After aliasing has been done, local and valid recipients who have a
|
||||
.Dq Pa .forward
|
||||
file in their home directory have messages forwarded to the
|
||||
.PP
|
||||
After aliasing has been done, local and valid recipients who have a
|
||||
``.forward''
|
||||
file in their home directory have messages forwarded to the
|
||||
list of users defined in that file.
|
||||
.Pp
|
||||
.PP
|
||||
This is only the raw data file; the actual aliasing information is
|
||||
placed into a binary format in the file
|
||||
.Pa /etc/aliases.db
|
||||
using the program
|
||||
.Xr newaliases 1 .
|
||||
A
|
||||
.Xr newaliases
|
||||
command should be executed each time the aliases file is changed for the
|
||||
placed into a binary format in the file
|
||||
/etc/mail/aliases.db
|
||||
using the program
|
||||
newaliases(1).
|
||||
A
|
||||
newaliases
|
||||
command should be executed each time the aliases file is changed for the
|
||||
change to take effect.
|
||||
.Sh SEE ALSO
|
||||
.Xr newaliases 1 ,
|
||||
.Xr dbm 3 ,
|
||||
.Xr dbopen 3 ,
|
||||
.Xr sendmail 8
|
||||
.Rs
|
||||
.%T "SENDMAIL Installation and Operation Guide"
|
||||
.Re
|
||||
.Rs
|
||||
.%T "SENDMAIL An Internetwork Mail Router"
|
||||
.Re
|
||||
.Sh BUGS
|
||||
If you have compiled
|
||||
.Xr sendmail
|
||||
.SH SEE ALSO
|
||||
newaliases(1),
|
||||
dbm(3),
|
||||
dbopen(3),
|
||||
db_open(3),
|
||||
sendmail(8)
|
||||
.PP
|
||||
.I
|
||||
SENDMAIL Installation and Operation Guide.
|
||||
.PP
|
||||
.I
|
||||
SENDMAIL An Internetwork Mail Router.
|
||||
.SH BUGS
|
||||
If you have compiled
|
||||
sendmail
|
||||
with DBM support instead of NEWDB,
|
||||
you may have encountered problems in
|
||||
.Xr dbm 3
|
||||
restricting a single alias to about 1000 bytes of information.
|
||||
You can get longer aliases by ``chaining''; that is, make the last name in
|
||||
you may have encountered problems in
|
||||
dbm(3)
|
||||
restricting a single alias to about 1000 bytes of information.
|
||||
You can get longer aliases by ``chaining''; that is, make the last name in
|
||||
the alias be a dummy name which is a continuation alias.
|
||||
.Sh HISTORY
|
||||
.SH HISTORY
|
||||
The
|
||||
.Nm
|
||||
file format appeared in
|
||||
.Bx 4.0 .
|
||||
.B aliases
|
||||
file format appeared in
|
||||
4.0BSD.
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
* Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -11,11 +12,22 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)err.c 8.74 (Berkeley) 6/4/1998";
|
||||
#endif /* not lint */
|
||||
static char id[] = "@(#)$Id: err.c,v 8.120.4.1 2000/05/25 18:56:15 gshapiro Exp $";
|
||||
#endif /* ! lint */
|
||||
|
||||
# include "sendmail.h"
|
||||
# include <errno.h>
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include <sendmail.h>
|
||||
#ifdef 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));
|
||||
|
||||
/*
|
||||
** SYSERR -- Print error message.
|
||||
@ -43,31 +55,29 @@ static char sccsid[] = "@(#)err.c 8.74 (Berkeley) 6/4/1998";
|
||||
** sets ExitStat.
|
||||
*/
|
||||
|
||||
char MsgBuf[BUFSIZ*2]; /* text of most recent message */
|
||||
char HeldMessageBuf[sizeof MsgBuf]; /* for held messages */
|
||||
|
||||
extern void putoutmsg __P((char *, bool, bool));
|
||||
extern void puterrmsg __P((char *));
|
||||
static void fmtmsg __P((char *, const char *, const char *, int, const char *, va_list));
|
||||
char MsgBuf[BUFSIZ*2]; /* text of most recent message */
|
||||
static char HeldMessageBuf[sizeof MsgBuf]; /* for held messages */
|
||||
|
||||
#if NAMED_BIND && !defined(NO_DATA)
|
||||
# define NO_DATA NO_ADDRESS
|
||||
#endif
|
||||
#endif /* NAMED_BIND && !defined(NO_DATA) */
|
||||
|
||||
void
|
||||
/*VARARGS1*/
|
||||
#ifdef __STDC__
|
||||
syserr(const char *fmt, ...)
|
||||
#else
|
||||
#else /* __STDC__ */
|
||||
syserr(fmt, va_alist)
|
||||
const char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
#endif /* __STDC__ */
|
||||
{
|
||||
register char *p;
|
||||
int olderrno = errno;
|
||||
int save_errno = errno;
|
||||
bool panic;
|
||||
char *uname;
|
||||
char *user;
|
||||
char *enhsc;
|
||||
char *errtxt;
|
||||
struct passwd *pw;
|
||||
char ubuf[80];
|
||||
VA_LOCAL_DECL
|
||||
@ -80,12 +90,18 @@ syserr(fmt, va_alist)
|
||||
}
|
||||
|
||||
/* format and output the error message */
|
||||
if (olderrno == 0)
|
||||
if (save_errno == 0)
|
||||
{
|
||||
p = "554";
|
||||
enhsc = "5.0.0";
|
||||
}
|
||||
else
|
||||
{
|
||||
p = "451";
|
||||
enhsc = "4.0.0";
|
||||
}
|
||||
VA_START(fmt);
|
||||
fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, ap);
|
||||
errtxt = fmtmsg(MsgBuf, (char *) NULL, p, enhsc, save_errno, fmt, ap);
|
||||
VA_END;
|
||||
puterrmsg(MsgBuf);
|
||||
|
||||
@ -94,35 +110,35 @@ syserr(fmt, va_alist)
|
||||
{
|
||||
if (CurEnv->e_message != NULL)
|
||||
free(CurEnv->e_message);
|
||||
CurEnv->e_message = newstr(MsgBuf + 4);
|
||||
CurEnv->e_message = newstr(errtxt);
|
||||
}
|
||||
|
||||
/* determine exit status if not already set */
|
||||
if (ExitStat == EX_OK)
|
||||
{
|
||||
if (olderrno == 0)
|
||||
if (save_errno == 0)
|
||||
ExitStat = EX_SOFTWARE;
|
||||
else
|
||||
ExitStat = EX_OSERR;
|
||||
if (tTd(54, 1))
|
||||
printf("syserr: ExitStat = %d\n", ExitStat);
|
||||
dprintf("syserr: ExitStat = %d\n", ExitStat);
|
||||
}
|
||||
|
||||
pw = sm_getpwuid(getuid());
|
||||
if (pw != NULL)
|
||||
uname = pw->pw_name;
|
||||
user = pw->pw_name;
|
||||
else
|
||||
{
|
||||
uname = ubuf;
|
||||
snprintf(ubuf, sizeof ubuf, "UID%d", getuid());
|
||||
user = ubuf;
|
||||
snprintf(ubuf, sizeof ubuf, "UID%d", (int) getuid());
|
||||
}
|
||||
|
||||
if (LogLevel > 0)
|
||||
sm_syslog(panic ? LOG_ALERT : LOG_CRIT,
|
||||
CurEnv == NULL ? NOQID : CurEnv->e_id,
|
||||
"SYSERR(%s): %.900s",
|
||||
uname, &MsgBuf[4]);
|
||||
switch (olderrno)
|
||||
user, errtxt);
|
||||
switch (save_errno)
|
||||
{
|
||||
case EBADF:
|
||||
case ENFILE:
|
||||
@ -130,19 +146,21 @@ syserr(fmt, va_alist)
|
||||
case ENOTTY:
|
||||
#ifdef EFBIG
|
||||
case EFBIG:
|
||||
#endif
|
||||
#endif /* EFBIG */
|
||||
#ifdef ESPIPE
|
||||
case ESPIPE:
|
||||
#endif
|
||||
#endif /* ESPIPE */
|
||||
#ifdef EPIPE
|
||||
case EPIPE:
|
||||
#endif
|
||||
#endif /* EPIPE */
|
||||
#ifdef ENOBUFS
|
||||
case ENOBUFS:
|
||||
#endif
|
||||
#endif /* ENOBUFS */
|
||||
#ifdef ESTALE
|
||||
case ESTALE:
|
||||
#endif
|
||||
#endif /* ESTALE */
|
||||
|
||||
|
||||
printopenfds(TRUE);
|
||||
mci_dump_all(TRUE);
|
||||
break;
|
||||
@ -151,7 +169,8 @@ syserr(fmt, va_alist)
|
||||
{
|
||||
#ifdef XLA
|
||||
xla_all_end();
|
||||
#endif
|
||||
#endif /* XLA */
|
||||
sync_queue_time();
|
||||
if (tTd(0, 1))
|
||||
abort();
|
||||
exit(EX_OSERR);
|
||||
@ -182,21 +201,31 @@ syserr(fmt, va_alist)
|
||||
void
|
||||
#ifdef __STDC__
|
||||
usrerr(const char *fmt, ...)
|
||||
#else
|
||||
#else /* __STDC__ */
|
||||
usrerr(fmt, va_alist)
|
||||
const char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
#endif /* __STDC__ */
|
||||
{
|
||||
char *enhsc;
|
||||
char *errtxt;
|
||||
VA_LOCAL_DECL
|
||||
|
||||
if (fmt[0] == '5' || fmt[0] == '6')
|
||||
enhsc = "5.0.0";
|
||||
else if (fmt[0] == '4' || fmt[0] == '8')
|
||||
enhsc = "4.0.0";
|
||||
else if (fmt[0] == '2')
|
||||
enhsc = "2.0.0";
|
||||
else
|
||||
enhsc = NULL;
|
||||
VA_START(fmt);
|
||||
errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "501", enhsc, 0, fmt, ap);
|
||||
VA_END;
|
||||
|
||||
if (SuprErrs)
|
||||
return;
|
||||
|
||||
VA_START(fmt);
|
||||
fmtmsg(MsgBuf, CurEnv->e_to, "501", 0, fmt, ap);
|
||||
VA_END;
|
||||
|
||||
/* save this message for mailq printing */
|
||||
switch (MsgBuf[0])
|
||||
{
|
||||
@ -205,7 +234,7 @@ usrerr(fmt, va_alist)
|
||||
if (CurEnv->e_message != NULL)
|
||||
break;
|
||||
|
||||
/* fall through.... */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case '5':
|
||||
case '6':
|
||||
@ -216,12 +245,12 @@ usrerr(fmt, va_alist)
|
||||
char buf[MAXLINE];
|
||||
|
||||
snprintf(buf, sizeof buf, "Postmaster warning: %.*s",
|
||||
(int)sizeof buf - 22, MsgBuf + 4);
|
||||
(int) sizeof buf - 22, errtxt);
|
||||
CurEnv->e_message = newstr(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurEnv->e_message = newstr(MsgBuf + 4);
|
||||
CurEnv->e_message = newstr(errtxt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -229,9 +258,93 @@ usrerr(fmt, va_alist)
|
||||
puterrmsg(MsgBuf);
|
||||
|
||||
if (LogLevel > 3 && LogUsrErrs)
|
||||
sm_syslog(LOG_NOTICE, CurEnv->e_id,
|
||||
"%.900s",
|
||||
&MsgBuf[4]);
|
||||
sm_syslog(LOG_NOTICE, CurEnv->e_id, "%.900s", errtxt);
|
||||
|
||||
if (QuickAbort)
|
||||
longjmp(TopFrame, 1);
|
||||
}
|
||||
/*
|
||||
** USRERRENH -- Signal user error.
|
||||
**
|
||||
** Same as usrerr but with enhanced status code.
|
||||
**
|
||||
** 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
|
||||
**
|
||||
** Returns:
|
||||
** none
|
||||
** Through TopFrame if QuickAbort is set.
|
||||
**
|
||||
** Side Effects:
|
||||
** increments Errors.
|
||||
*/
|
||||
|
||||
/*VARARGS1*/
|
||||
void
|
||||
#ifdef __STDC__
|
||||
usrerrenh(char *enhsc, const char *fmt, ...)
|
||||
#else /* __STDC__ */
|
||||
usrerrenh(enhsc, fmt, va_alist)
|
||||
char *enhsc;
|
||||
const char *fmt;
|
||||
va_dcl
|
||||
#endif /* __STDC__ */
|
||||
{
|
||||
char *errtxt;
|
||||
VA_LOCAL_DECL
|
||||
|
||||
if (enhsc == NULL || *enhsc == '\0')
|
||||
{
|
||||
if (fmt[0] == '5' || fmt[0] == '6')
|
||||
enhsc = "5.0.0";
|
||||
else if (fmt[0] == '4' || fmt[0] == '8')
|
||||
enhsc = "4.0.0";
|
||||
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;
|
||||
|
||||
if (SuprErrs)
|
||||
return;
|
||||
|
||||
/* save this message for mailq printing */
|
||||
switch (MsgBuf[0])
|
||||
{
|
||||
case '4':
|
||||
case '8':
|
||||
if (CurEnv->e_message != NULL)
|
||||
break;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case '5':
|
||||
case '6':
|
||||
if (CurEnv->e_message != NULL)
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurEnv->e_message = newstr(errtxt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
puterrmsg(MsgBuf);
|
||||
|
||||
if (LogLevel > 3 && LogUsrErrs)
|
||||
sm_syslog(LOG_NOTICE, CurEnv->e_id, "%.900s", errtxt);
|
||||
|
||||
if (QuickAbort)
|
||||
longjmp(TopFrame, 1);
|
||||
@ -255,17 +368,18 @@ usrerr(fmt, va_alist)
|
||||
void
|
||||
#ifdef __STDC__
|
||||
message(const char *msg, ...)
|
||||
#else
|
||||
#else /* __STDC__ */
|
||||
message(msg, va_alist)
|
||||
const char *msg;
|
||||
va_dcl
|
||||
#endif
|
||||
#endif /* __STDC__ */
|
||||
{
|
||||
char *errtxt;
|
||||
VA_LOCAL_DECL
|
||||
|
||||
errno = 0;
|
||||
VA_START(msg);
|
||||
fmtmsg(MsgBuf, CurEnv->e_to, "050", 0, msg, ap);
|
||||
errtxt = fmtmsg(MsgBuf, CurEnv->e_to, "050", (char *) NULL, 0, msg, ap);
|
||||
VA_END;
|
||||
putoutmsg(MsgBuf, FALSE, FALSE);
|
||||
|
||||
@ -276,12 +390,12 @@ message(msg, va_alist)
|
||||
case '8':
|
||||
if (CurEnv->e_message != NULL)
|
||||
break;
|
||||
/* fall through.... */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case '5':
|
||||
if (CurEnv->e_message != NULL)
|
||||
free(CurEnv->e_message);
|
||||
CurEnv->e_message = newstr(MsgBuf + 4);
|
||||
CurEnv->e_message = newstr(errtxt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -307,17 +421,19 @@ message(msg, va_alist)
|
||||
void
|
||||
#ifdef __STDC__
|
||||
nmessage(const char *msg, ...)
|
||||
#else
|
||||
#else /* __STDC__ */
|
||||
nmessage(msg, va_alist)
|
||||
const char *msg;
|
||||
va_dcl
|
||||
#endif
|
||||
#endif /* __STDC__ */
|
||||
{
|
||||
char *errtxt;
|
||||
VA_LOCAL_DECL
|
||||
|
||||
errno = 0;
|
||||
VA_START(msg);
|
||||
fmtmsg(MsgBuf, (char *) NULL, "050", 0, msg, ap);
|
||||
errtxt = fmtmsg(MsgBuf, (char *) NULL, "050",
|
||||
(char *) NULL, 0, msg, ap);
|
||||
VA_END;
|
||||
putoutmsg(MsgBuf, FALSE, FALSE);
|
||||
|
||||
@ -328,12 +444,12 @@ nmessage(msg, va_alist)
|
||||
case '8':
|
||||
if (CurEnv->e_message != NULL)
|
||||
break;
|
||||
/* fall through.... */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case '5':
|
||||
if (CurEnv->e_message != NULL)
|
||||
free(CurEnv->e_message);
|
||||
CurEnv->e_message = newstr(MsgBuf + 4);
|
||||
CurEnv->e_message = newstr(errtxt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -356,17 +472,18 @@ nmessage(msg, va_alist)
|
||||
** Deletes SMTP reply code number as appropriate.
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
putoutmsg(msg, holdmsg, heldmsg)
|
||||
char *msg;
|
||||
bool holdmsg;
|
||||
bool heldmsg;
|
||||
{
|
||||
char *errtxt = msg;
|
||||
char msgcode = msg[0];
|
||||
|
||||
/* display for debugging */
|
||||
if (tTd(54, 8))
|
||||
printf("--- %s%s%s\n", msg, holdmsg ? " (hold)" : "",
|
||||
dprintf("--- %s%s%s\n", msg, holdmsg ? " (hold)" : "",
|
||||
heldmsg ? " (held)" : "");
|
||||
|
||||
/* map warnings to something SMTP can handle */
|
||||
@ -382,8 +499,8 @@ putoutmsg(msg, holdmsg, heldmsg)
|
||||
|
||||
if (LogLevel >= 15 && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
|
||||
sm_syslog(LOG_INFO, CurEnv->e_id,
|
||||
"--> %s%s",
|
||||
msg, holdmsg ? " (held)" : "");
|
||||
"--> %s%s",
|
||||
msg, holdmsg ? " (held)" : "");
|
||||
|
||||
if (msgcode == '8')
|
||||
msg[0] = '0';
|
||||
@ -395,6 +512,8 @@ putoutmsg(msg, holdmsg, heldmsg)
|
||||
{
|
||||
/* save for possible future display */
|
||||
msg[0] = msgcode;
|
||||
if (HeldMessageBuf[0] == '5' && msgcode == '4')
|
||||
return;
|
||||
snprintf(HeldMessageBuf, sizeof HeldMessageBuf, "%s", msg);
|
||||
return;
|
||||
}
|
||||
@ -403,16 +522,29 @@ putoutmsg(msg, holdmsg, heldmsg)
|
||||
|
||||
if (OutChannel == NULL)
|
||||
return;
|
||||
|
||||
|
||||
/* find actual text of error (after SMTP status codes) */
|
||||
if (ISSMTPREPLY(errtxt))
|
||||
{
|
||||
int l;
|
||||
|
||||
errtxt += 4;
|
||||
l = isenhsc(errtxt, ' ');
|
||||
if (l <= 0)
|
||||
l = isenhsc(errtxt, '\0');
|
||||
if (l > 0)
|
||||
errtxt += l + 1;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
else
|
||||
fprintf(OutChannel, "%s\n", &msg[4]);
|
||||
fprintf(OutChannel, "%s\n", errtxt);
|
||||
if (TrafficLogFile != NULL)
|
||||
fprintf(TrafficLogFile, "%05d >>> %s\n", (int) getpid(),
|
||||
(OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : &msg[4]);
|
||||
(OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : errtxt);
|
||||
if (msg[3] == ' ')
|
||||
(void) fflush(OutChannel);
|
||||
if (!ferror(OutChannel) || DisConnected)
|
||||
@ -432,9 +564,9 @@ putoutmsg(msg, holdmsg, heldmsg)
|
||||
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));
|
||||
"SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s",
|
||||
CurHostName == NULL ? "NO-HOST" : CurHostName,
|
||||
shortenstring(msg, MAXSHORTSTR), errstring(errno));
|
||||
}
|
||||
/*
|
||||
** PUTERRMSG -- like putoutmsg, but does special processing for error messages
|
||||
@ -449,7 +581,7 @@ putoutmsg(msg, holdmsg, heldmsg)
|
||||
** Sets the fatal error bit in the envelope as appropriate.
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
puterrmsg(msg)
|
||||
char *msg;
|
||||
{
|
||||
@ -467,7 +599,7 @@ puterrmsg(msg)
|
||||
|
||||
if (CurEnv == NULL)
|
||||
return;
|
||||
|
||||
|
||||
if (msgcode == '6')
|
||||
{
|
||||
/* notify the postmaster */
|
||||
@ -480,28 +612,122 @@ puterrmsg(msg)
|
||||
}
|
||||
}
|
||||
/*
|
||||
** ISENHSC -- check whether a string contains an enhanced status code
|
||||
**
|
||||
** Parameters:
|
||||
** s -- string with possible enhanced status code.
|
||||
** delim -- delim for enhanced status code.
|
||||
**
|
||||
** Returns:
|
||||
** 0 -- no enhanced status code.
|
||||
** >4 -- length of enhanced status code.
|
||||
**
|
||||
** Side Effects:
|
||||
** none.
|
||||
*/
|
||||
int
|
||||
isenhsc(s, delim)
|
||||
const char *s;
|
||||
int delim;
|
||||
{
|
||||
int l, h;
|
||||
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
if (!((*s == '2' || *s == '4' || *s == '5') && s[1] == '.'))
|
||||
return 0;
|
||||
h = 0;
|
||||
l = 2;
|
||||
while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h]))
|
||||
++h;
|
||||
if (h == 0 || s[l + h] != '.')
|
||||
return 0;
|
||||
l += h + 1;
|
||||
h = 0;
|
||||
while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h]))
|
||||
++h;
|
||||
if (h == 0 || s[l + h] != delim)
|
||||
return 0;
|
||||
return l + h;
|
||||
}
|
||||
/*
|
||||
** EXTENHSC -- check and extract an enhanced status code
|
||||
**
|
||||
** Parameters:
|
||||
** s -- string with possible enhanced status code.
|
||||
** delim -- delim for enhanced status code.
|
||||
** e -- pointer to storage for enhanced status code.
|
||||
** must be != NULL and have space for at least
|
||||
** 10 characters ([245].[0-9]{1,3}.[0-9]{1,3})
|
||||
**
|
||||
** Returns:
|
||||
** 0 -- no enhanced status code.
|
||||
** >4 -- length of enhanced status code.
|
||||
**
|
||||
** Side Effects:
|
||||
** fills e with enhanced status code.
|
||||
*/
|
||||
int
|
||||
extenhsc(s, delim, e)
|
||||
const char *s;
|
||||
int delim;
|
||||
char *e;
|
||||
{
|
||||
int l, h;
|
||||
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
if (!((*s == '2' || *s == '4' || *s == '5') && s[1] == '.'))
|
||||
return 0;
|
||||
h = 0;
|
||||
l = 2;
|
||||
e[0] = s[0];
|
||||
e[1] = '.';
|
||||
while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h]))
|
||||
{
|
||||
e[l + h] = s[l + h];
|
||||
++h;
|
||||
}
|
||||
if (h == 0 || s[l + h] != '.')
|
||||
return 0;
|
||||
e[l + h] = '.';
|
||||
l += h + 1;
|
||||
h = 0;
|
||||
while (h < 3 && isascii(s[l + h]) && isdigit(s[l + h]))
|
||||
{
|
||||
e[l + h] = s[l + h];
|
||||
++h;
|
||||
}
|
||||
if (h == 0 || s[l + h] != delim)
|
||||
return 0;
|
||||
e[l + h] = '\0';
|
||||
return l + h;
|
||||
}
|
||||
/*
|
||||
** FMTMSG -- format a message into buffer.
|
||||
**
|
||||
** Parameters:
|
||||
** eb -- error buffer to get result.
|
||||
** eb -- error buffer to get result -- MUST BE MsgBuf.
|
||||
** to -- the recipient tag for this message.
|
||||
** num -- arpanet error number.
|
||||
** num -- default three digit SMTP reply code.
|
||||
** enhsc -- enhanced status code.
|
||||
** en -- the error number to display.
|
||||
** fmt -- format of string.
|
||||
** a, b, c, d, e -- arguments.
|
||||
** ap -- arguments for fmt.
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
** pointer to error text beyond status codes.
|
||||
**
|
||||
** Side Effects:
|
||||
** none.
|
||||
*/
|
||||
|
||||
static void
|
||||
fmtmsg(eb, to, num, eno, fmt, ap)
|
||||
static char *
|
||||
fmtmsg(eb, to, num, enhsc, eno, fmt, ap)
|
||||
register char *eb;
|
||||
const char *to;
|
||||
const char *num;
|
||||
const char *enhsc;
|
||||
int eno;
|
||||
const char *fmt;
|
||||
va_list ap;
|
||||
@ -509,11 +735,10 @@ fmtmsg(eb, to, num, eno, fmt, ap)
|
||||
char del;
|
||||
int l;
|
||||
int spaceleft = sizeof MsgBuf;
|
||||
char *errtxt;
|
||||
|
||||
/* output the reply code */
|
||||
if (isascii(fmt[0]) && isdigit(fmt[0]) &&
|
||||
isascii(fmt[1]) && isdigit(fmt[1]) &&
|
||||
isascii(fmt[2]) && isdigit(fmt[2]))
|
||||
if (ISSMTPCODE(fmt))
|
||||
{
|
||||
num = fmt;
|
||||
fmt += 4;
|
||||
@ -526,6 +751,26 @@ fmtmsg(eb, to, num, eno, fmt, ap)
|
||||
eb += 4;
|
||||
spaceleft -= 4;
|
||||
|
||||
if ((l = isenhsc(fmt, ' ' )) > 0 && l < spaceleft - 4)
|
||||
{
|
||||
/* copy enh.status code including trailing blank */
|
||||
l++;
|
||||
(void) strlcpy(eb, fmt, l + 1);
|
||||
eb += l;
|
||||
spaceleft -= l;
|
||||
fmt += l;
|
||||
}
|
||||
else if ((l = isenhsc(enhsc, '\0')) > 0 && l < spaceleft - 4)
|
||||
{
|
||||
/* copy enh.status code */
|
||||
(void) strlcpy(eb, enhsc, l + 1);
|
||||
eb[l] = ' ';
|
||||
eb[++l] = '\0';
|
||||
eb += l;
|
||||
spaceleft -= l;
|
||||
}
|
||||
errtxt = eb;
|
||||
|
||||
/* output the file name and line number */
|
||||
if (FileName != NULL)
|
||||
{
|
||||
@ -556,6 +801,8 @@ fmtmsg(eb, to, num, eno, fmt, ap)
|
||||
/* output the error code, if any */
|
||||
if (eno != 0)
|
||||
(void) snprintf(eb, spaceleft, ": %s", errstring(eno));
|
||||
|
||||
return errtxt;
|
||||
}
|
||||
/*
|
||||
** BUFFER_ERRORS -- arrange to buffer future error messages
|
||||
@ -613,13 +860,10 @@ errstring(errnum)
|
||||
char *dnsmsg;
|
||||
char *bp;
|
||||
static char buf[MAXLINE];
|
||||
# if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
|
||||
#if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
|
||||
extern char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
# endif
|
||||
# if SMTP
|
||||
extern char *SmtpPhase;
|
||||
# endif /* SMTP */
|
||||
#endif /* !HASSTRERROR && !defined(ERRLIST_PREDEFINED) */
|
||||
|
||||
/*
|
||||
** Handle special network error codes.
|
||||
@ -630,18 +874,18 @@ errstring(errnum)
|
||||
dnsmsg = NULL;
|
||||
switch (errnum)
|
||||
{
|
||||
# if defined(DAEMON) && defined(ETIMEDOUT)
|
||||
#if defined(DAEMON) && defined(ETIMEDOUT)
|
||||
case ETIMEDOUT:
|
||||
case ECONNRESET:
|
||||
bp = buf;
|
||||
#if HASSTRERROR
|
||||
# if HASSTRERROR
|
||||
snprintf(bp, SPACELEFT(buf, bp), "%s", strerror(errnum));
|
||||
#else
|
||||
# else /* HASSTRERROR */
|
||||
if (errnum >= 0 && errnum < sys_nerr)
|
||||
snprintf(bp, SPACELEFT(buf, bp), "%s", sys_errlist[errnum]);
|
||||
else
|
||||
snprintf(bp, SPACELEFT(buf, bp), "Error %d", errnum);
|
||||
#endif
|
||||
# endif /* HASSTRERROR */
|
||||
bp += strlen(bp);
|
||||
if (CurHostName != NULL)
|
||||
{
|
||||
@ -666,24 +910,24 @@ errstring(errnum)
|
||||
snprintf(bp, SPACELEFT(buf, bp), " during %s",
|
||||
SmtpPhase);
|
||||
}
|
||||
return (buf);
|
||||
return buf;
|
||||
|
||||
case EHOSTDOWN:
|
||||
if (CurHostName == NULL)
|
||||
break;
|
||||
(void) snprintf(buf, sizeof buf, "Host %s is down",
|
||||
shortenstring(CurHostName, MAXSHORTSTR));
|
||||
return (buf);
|
||||
return buf;
|
||||
|
||||
case ECONNREFUSED:
|
||||
if (CurHostName == NULL)
|
||||
break;
|
||||
(void) snprintf(buf, sizeof buf, "Connection refused by %s",
|
||||
shortenstring(CurHostName, MAXSHORTSTR));
|
||||
return (buf);
|
||||
# endif
|
||||
return buf;
|
||||
#endif /* defined(DAEMON) && defined(ETIMEDOUT) */
|
||||
|
||||
# if NAMED_BIND
|
||||
#if NAMED_BIND
|
||||
case HOST_NOT_FOUND + E_DNSBASE:
|
||||
dnsmsg = "host not found";
|
||||
break;
|
||||
@ -699,7 +943,7 @@ errstring(errnum)
|
||||
case NO_DATA + E_DNSBASE:
|
||||
dnsmsg = "no data known";
|
||||
break;
|
||||
# endif
|
||||
#endif /* NAMED_BIND */
|
||||
|
||||
case EPERM:
|
||||
/* SunOS gives "Not owner" -- this is the POSIX message */
|
||||
@ -738,13 +982,18 @@ errstring(errnum)
|
||||
|
||||
case E_SM_GWFILE:
|
||||
return "Group writable file";
|
||||
|
||||
case E_SM_GRFILE:
|
||||
return "Group readable file";
|
||||
|
||||
case E_SM_WRFILE:
|
||||
return "World readable file";
|
||||
}
|
||||
|
||||
if (dnsmsg != NULL)
|
||||
{
|
||||
bp = buf;
|
||||
strcpy(bp, "Name server: ");
|
||||
bp += strlen(bp);
|
||||
bp += strlcpy(bp, "Name server: ", sizeof buf);
|
||||
if (CurHostName != NULL)
|
||||
{
|
||||
snprintf(bp, SPACELEFT(buf, bp), "%s: ",
|
||||
@ -755,13 +1004,18 @@ errstring(errnum)
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef LDAPMAP
|
||||
if (errnum >= E_LDAPBASE)
|
||||
return ldap_err2string(errnum - E_LDAPBASE);
|
||||
#endif /* LDAPMAP */
|
||||
|
||||
#if HASSTRERROR
|
||||
return strerror(errnum);
|
||||
#else
|
||||
#else /* HASSTRERROR */
|
||||
if (errnum > 0 && errnum < sys_nerr)
|
||||
return (sys_errlist[errnum]);
|
||||
return sys_errlist[errnum];
|
||||
|
||||
(void) snprintf(buf, sizeof buf, "Error %d", errnum);
|
||||
return (buf);
|
||||
#endif
|
||||
return buf;
|
||||
#endif /* HASSTRERROR */
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
||||
.\" Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
.\" Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1983, 1997 Eric P. Allman. All rights reserved.
|
||||
.\" Copyright (c) 1985, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@ -8,53 +9,59 @@
|
||||
.\" the sendmail distribution.
|
||||
.\"
|
||||
.\"
|
||||
.\" @(#)mailq.1 8.10 (Berkeley) 5/19/1998
|
||||
.\" $Id: mailq.1,v 8.14.28.1 2000/07/14 05:07:01 gshapiro Exp $
|
||||
.\"
|
||||
.Dd May 19, 1998
|
||||
.Dt MAILQ 1
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm mailq
|
||||
.Nd print the mail queue
|
||||
.Sh SYNOPSIS
|
||||
.Nm mailq
|
||||
.Op Fl v
|
||||
.Sh DESCRIPTION
|
||||
.Nm Mailq
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.TH MAILQ 1 "$Date: 2000/07/14 05:07:01 $"
|
||||
.SH NAME
|
||||
.B mailq
|
||||
\- print the mail queue
|
||||
.SH SYNOPSIS
|
||||
.B mailq
|
||||
.RB [ \-v ]
|
||||
.SH DESCRIPTION
|
||||
.B Mailq
|
||||
prints a summary of the mail messages queued for future delivery.
|
||||
.Pp
|
||||
The first line printed for each message
|
||||
shows the internal identifier used on this host
|
||||
for the message,
|
||||
.PP
|
||||
The first line printed for each message
|
||||
shows the internal identifier used on this host
|
||||
for the message with a possible status character,
|
||||
the size of the message in bytes,
|
||||
the date and time the message was accepted into the queue,
|
||||
and the envelope sender of the message.
|
||||
The second line shows the error message that caused this message
|
||||
to be retained in the queue;
|
||||
it will not be present if the message is being processed
|
||||
for the first time.
|
||||
The following lines show message recipients,
|
||||
the date and time the message was accepted into the queue,
|
||||
and the envelope sender of the message.
|
||||
The second line shows the error message that caused this message
|
||||
to be retained in the queue;
|
||||
it will not be present if the message is being processed
|
||||
for the first time.
|
||||
The status characters are either
|
||||
.B *
|
||||
to indicate the job is being processed;
|
||||
.B X
|
||||
to indicate that the load is too high to process the job; and
|
||||
.B -
|
||||
to indicate that the job is too young to process.
|
||||
The following lines show message recipients,
|
||||
one per line.
|
||||
.Pp
|
||||
.PP
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl v
|
||||
Print verbose information.
|
||||
This adds the priority of the message and
|
||||
a single character indicator (``+'' or blank)
|
||||
indicating whether a warning message has been sent
|
||||
.TP
|
||||
.B \-v
|
||||
Print verbose information.
|
||||
This adds the priority of the message and
|
||||
a single character indicator (``+'' or blank)
|
||||
indicating whether a warning message has been sent
|
||||
on the first line of the message.
|
||||
Additionally, extra lines may be intermixed with the recipients
|
||||
indicating the ``controlling user'' information;
|
||||
this shows who will own any programs that are executed
|
||||
on behalf of this message
|
||||
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.
|
||||
.El
|
||||
.Pp
|
||||
.PP
|
||||
The
|
||||
.Nm mailq
|
||||
.B mailq
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh NOTES
|
||||
.SH NOTES
|
||||
.Nm Mailq
|
||||
is identical to
|
||||
.Dq Li "sendmail -bp" .
|
||||
@ -62,10 +69,10 @@ Most of the options which apply to
|
||||
.Xr sendmail 8
|
||||
also apply to
|
||||
.Nm mailq .
|
||||
.Sh SEE ALSO
|
||||
.Xr sendmail 8
|
||||
.Sh HISTORY
|
||||
.SH SEE ALSO
|
||||
sendmail(8)
|
||||
.SH HISTORY
|
||||
The
|
||||
.Nm mailq
|
||||
command appeared in
|
||||
.Bx 4.0 .
|
||||
.B mailq
|
||||
command appeared in
|
||||
4.0BSD.
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Sendmail, Inc. All rights reserved.
|
||||
* Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1995-1997 Eric P. Allman. All rights reserved.
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -11,13 +12,27 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)mci.c 8.83 (Berkeley) 10/13/1998";
|
||||
#endif /* not lint */
|
||||
static char id[] = "@(#)$Id: mci.c,v 8.133.10.3 2000/06/23 16:17:06 ca Exp $";
|
||||
#endif /* ! lint */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include <sendmail.h>
|
||||
|
||||
|
||||
#if NETINET || NETINET6
|
||||
# include <arpa/inet.h>
|
||||
#endif /* NETINET || NETINET6 */
|
||||
|
||||
#include "sendmail.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <dirent.h>
|
||||
|
||||
static int mci_generate_persistent_path __P((const char *, char *,
|
||||
int, bool));
|
||||
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 *));
|
||||
|
||||
/*
|
||||
** Mail Connection Information (MCI) Caching Module.
|
||||
**
|
||||
@ -49,11 +64,8 @@ static char sccsid[] = "@(#)mci.c 8.83 (Berkeley) 10/13/1998";
|
||||
** MCI structure.
|
||||
*/
|
||||
|
||||
MCI **MciCache; /* the open connection cache */
|
||||
static MCI **MciCache; /* the open connection cache */
|
||||
|
||||
extern int mci_generate_persistent_path __P((const char *, char *, int, bool));
|
||||
extern bool mci_load_persistent __P((MCI *));
|
||||
extern void mci_uncache __P((MCI **, bool));
|
||||
/*
|
||||
** MCI_CACHE -- enter a connection structure into the open connection cache
|
||||
**
|
||||
@ -96,12 +108,13 @@ mci_cache(mci)
|
||||
mci_uncache(mcislot, TRUE);
|
||||
|
||||
if (tTd(42, 5))
|
||||
printf("mci_cache: caching %lx (%s) in slot %d\n",
|
||||
(u_long) mci, mci->mci_host, (int)(mcislot - MciCache));
|
||||
dprintf("mci_cache: caching %lx (%s) in slot %d\n",
|
||||
(u_long) mci, mci->mci_host,
|
||||
(int)(mcislot - MciCache));
|
||||
if (tTd(91, 100))
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"mci_cache: caching %x (%.100s) in slot %d",
|
||||
mci, mci->mci_host, mcislot - MciCache);
|
||||
"mci_cache: caching %lx (%.100s) in slot %d",
|
||||
(u_long) mci, mci->mci_host, mcislot - MciCache);
|
||||
|
||||
*mcislot = mci;
|
||||
mci->mci_flags |= MCIF_CACHED;
|
||||
@ -135,8 +148,8 @@ mci_scan(savemci)
|
||||
{
|
||||
/* first call */
|
||||
MciCache = (MCI **) xalloc(MaxMciCache * sizeof *MciCache);
|
||||
bzero((char *) MciCache, MaxMciCache * sizeof *MciCache);
|
||||
return (&MciCache[0]);
|
||||
memset((char *) MciCache, '\0', MaxMciCache * sizeof *MciCache);
|
||||
return &MciCache[0];
|
||||
}
|
||||
|
||||
now = curtime();
|
||||
@ -149,10 +162,16 @@ mci_scan(savemci)
|
||||
bestmci = &MciCache[i];
|
||||
continue;
|
||||
}
|
||||
if (mci->mci_lastuse + MciCacheTimeout < now && mci != savemci)
|
||||
if ((mci->mci_lastuse + MciCacheTimeout < now ||
|
||||
(mci->mci_mailer != NULL &&
|
||||
mci->mci_mailer->m_maxdeliveries > 0 &&
|
||||
mci->mci_deliveries + 1 >= mci->mci_mailer->m_maxdeliveries))&&
|
||||
mci != savemci)
|
||||
{
|
||||
/* connection idle too long -- close it */
|
||||
/* connection idle too long or too many deliveries */
|
||||
bestmci = &MciCache[i];
|
||||
|
||||
/* close it */
|
||||
mci_uncache(bestmci, TRUE);
|
||||
continue;
|
||||
}
|
||||
@ -178,7 +197,7 @@ mci_scan(savemci)
|
||||
** none.
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
mci_uncache(mcislot, doquit)
|
||||
register MCI **mcislot;
|
||||
bool doquit;
|
||||
@ -196,14 +215,16 @@ mci_uncache(mcislot, doquit)
|
||||
mci_unlock_host(mci);
|
||||
|
||||
if (tTd(42, 5))
|
||||
printf("mci_uncache: uncaching %lx (%s) from slot %d (%d)\n",
|
||||
dprintf("mci_uncache: uncaching %lx (%s) from slot %d (%d)\n",
|
||||
(u_long) mci, mci->mci_host,
|
||||
(int)(mcislot - MciCache), doquit);
|
||||
if (tTd(91, 100))
|
||||
sm_syslog(LOG_DEBUG, CurEnv->e_id,
|
||||
"mci_uncache: uncaching %x (%.100s) from slot %d (%d)",
|
||||
mci, mci->mci_host, mcislot - MciCache, doquit);
|
||||
"mci_uncache: uncaching %lx (%.100s) from slot %d (%d)",
|
||||
(u_long) mci, mci->mci_host,
|
||||
mcislot - MciCache, doquit);
|
||||
|
||||
mci->mci_deliveries = 0;
|
||||
#if SMTP
|
||||
if (doquit)
|
||||
{
|
||||
@ -214,17 +235,17 @@ 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
|
||||
# ifdef XLA
|
||||
xla_host_end(mci->mci_host);
|
||||
#endif
|
||||
# endif /* XLA */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif /* SMTP */
|
||||
{
|
||||
if (mci->mci_in != NULL)
|
||||
xfclose(mci->mci_in, "mci_uncache", "mci_in");
|
||||
(void) fclose(mci->mci_in);
|
||||
if (mci->mci_out != NULL)
|
||||
xfclose(mci->mci_out, "mci_uncache", "mci_out");
|
||||
(void) fclose(mci->mci_out);
|
||||
mci->mci_in = mci->mci_out = NULL;
|
||||
mci->mci_state = MCIS_CLOSED;
|
||||
mci->mci_exitstat = EX_OK;
|
||||
@ -274,22 +295,30 @@ mci_get(host, m)
|
||||
extern SOCKADDR CurHostAddr;
|
||||
|
||||
/* clear CurHostAddr so we don't get a bogus address with this name */
|
||||
bzero(&CurHostAddr, sizeof CurHostAddr);
|
||||
#endif
|
||||
memset(&CurHostAddr, '\0', sizeof CurHostAddr);
|
||||
#endif /* DAEMON */
|
||||
|
||||
/* clear out any expired connections */
|
||||
(void) mci_scan(NULL);
|
||||
|
||||
if (m->m_mno < 0)
|
||||
syserr("negative mno %d (%s)", m->m_mno, m->m_name);
|
||||
|
||||
s = stab(host, ST_MCI + m->m_mno, ST_ENTER);
|
||||
mci = &s->s_mci;
|
||||
mci->mci_host = s->s_name;
|
||||
|
||||
if (!mci_load_persistent(mci))
|
||||
/*
|
||||
** We don't need to load the peristent data if we have data
|
||||
** already loaded in the cache.
|
||||
*/
|
||||
|
||||
if (mci->mci_host == NULL &&
|
||||
(mci->mci_host = s->s_name) != NULL &&
|
||||
!mci_load_persistent(mci))
|
||||
{
|
||||
if (tTd(42, 2))
|
||||
printf("mci_get(%s %s): lock failed\n", host, m->m_name);
|
||||
dprintf("mci_get(%s %s): lock failed\n",
|
||||
host, m->m_name);
|
||||
mci->mci_exitstat = EX_TEMPFAIL;
|
||||
mci->mci_state = MCIS_CLOSED;
|
||||
mci->mci_statfile = NULL;
|
||||
@ -298,7 +327,7 @@ mci_get(host, m)
|
||||
|
||||
if (tTd(42, 2))
|
||||
{
|
||||
printf("mci_get(%s %s): mci_state=%d, _flags=%x, _exitstat=%d, _errno=%d\n",
|
||||
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);
|
||||
}
|
||||
@ -306,8 +335,6 @@ mci_get(host, m)
|
||||
#if SMTP
|
||||
if (mci->mci_state == MCIS_OPEN)
|
||||
{
|
||||
extern int smtpprobe __P((MCI *));
|
||||
|
||||
/* poke the connection to see if it's still alive */
|
||||
(void) smtpprobe(mci);
|
||||
|
||||
@ -328,9 +355,9 @@ mci_get(host, m)
|
||||
(void) getpeername(fileno(mci->mci_in),
|
||||
(struct sockaddr *) &CurHostAddr, &socklen);
|
||||
}
|
||||
# endif
|
||||
# endif /* DAEMON */
|
||||
}
|
||||
#endif
|
||||
#endif /* SMTP */
|
||||
if (mci->mci_state == MCIS_CLOSED)
|
||||
{
|
||||
time_t now = curtime();
|
||||
@ -347,6 +374,29 @@ mci_get(host, m)
|
||||
return mci;
|
||||
}
|
||||
/*
|
||||
** MCI_MATCH -- check connection cache for a particular host
|
||||
*/
|
||||
|
||||
bool
|
||||
mci_match(host, m)
|
||||
char *host;
|
||||
MAILER *m;
|
||||
{
|
||||
register MCI *mci;
|
||||
register STAB *s;
|
||||
|
||||
if (m->m_mno < 0)
|
||||
return FALSE;
|
||||
s = stab(host, ST_MCI + m->m_mno, ST_FIND);
|
||||
if (s == NULL)
|
||||
return FALSE;
|
||||
|
||||
mci = &s->s_mci;
|
||||
if (mci->mci_state == MCIS_OPEN)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
** MCI_SETSTAT -- set status codes in MCI structure.
|
||||
**
|
||||
** Parameters:
|
||||
@ -395,7 +445,7 @@ struct mcifbits
|
||||
int mcif_bit; /* flag bit */
|
||||
char *mcif_name; /* flag name */
|
||||
};
|
||||
struct mcifbits MciFlags[] =
|
||||
static struct mcifbits MciFlags[] =
|
||||
{
|
||||
{ MCIF_VALID, "VALID" },
|
||||
{ MCIF_TEMP, "TEMP" },
|
||||
@ -424,7 +474,6 @@ mci_dump(mci, logit)
|
||||
register char *p;
|
||||
char *sep;
|
||||
char buf[4000];
|
||||
extern char *ctime();
|
||||
|
||||
sep = logit ? " " : "\n\t";
|
||||
p = buf;
|
||||
@ -437,7 +486,7 @@ mci_dump(mci, logit)
|
||||
snprintf(p, SPACELEFT(buf, p), "NULL");
|
||||
goto printit;
|
||||
}
|
||||
snprintf(p, SPACELEFT(buf, p), "flags=%x", mci->mci_flags);
|
||||
snprintf(p, SPACELEFT(buf, p), "flags=%lx", mci->mci_flags);
|
||||
p += strlen(p);
|
||||
if (mci->mci_flags != 0)
|
||||
{
|
||||
@ -456,7 +505,7 @@ mci_dump(mci, logit)
|
||||
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, mci->mci_pid, sep);
|
||||
mci->mci_exitstat, mci->mci_state, (int) mci->mci_pid, sep);
|
||||
p += strlen(p);
|
||||
snprintf(p, SPACELEFT(buf, p),
|
||||
"maxsize=%ld, phase=%s, mailer=%s,%s",
|
||||
@ -519,7 +568,7 @@ mci_dump_all(logit)
|
||||
** mci -- containing the host we want to lock.
|
||||
**
|
||||
** Returns:
|
||||
** EX_OK -- got the lock.
|
||||
** EX_OK -- got the lock.
|
||||
** EX_TEMPFAIL -- didn't get the lock.
|
||||
*/
|
||||
|
||||
@ -530,7 +579,7 @@ mci_lock_host(mci)
|
||||
if (mci == NULL)
|
||||
{
|
||||
if (tTd(56, 1))
|
||||
printf("mci_lock_host: NULL mci\n");
|
||||
dprintf("mci_lock_host: NULL mci\n");
|
||||
return EX_OK;
|
||||
}
|
||||
|
||||
@ -540,34 +589,34 @@ mci_lock_host(mci)
|
||||
return mci_lock_host_statfile(mci);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
mci_lock_host_statfile(mci)
|
||||
MCI *mci;
|
||||
{
|
||||
int savedErrno = errno;
|
||||
int save_errno = errno;
|
||||
int retVal = EX_OK;
|
||||
char fname[MAXPATHLEN+1];
|
||||
char fname[MAXPATHLEN + 1];
|
||||
|
||||
if (HostStatDir == NULL || mci->mci_host == NULL)
|
||||
return EX_OK;
|
||||
|
||||
if (tTd(56, 2))
|
||||
printf("mci_lock_host: attempting to lock %s\n",
|
||||
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)
|
||||
{
|
||||
/* of course this should never happen */
|
||||
if (tTd(56, 2))
|
||||
printf("mci_lock_host: Failed to generate host path for %s\n",
|
||||
mci->mci_host);
|
||||
dprintf("mci_lock_host: Failed to generate host path for %s\n",
|
||||
mci->mci_host);
|
||||
|
||||
retVal = EX_TEMPFAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
mci->mci_statfile = safefopen(fname, O_RDWR, FileMode,
|
||||
SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY|SFF_SAFEDIRPATH|SFF_CREAT);
|
||||
SFF_NOLOCK|SFF_NOLINK|SFF_OPENASROOT|SFF_REGONLY|SFF_SAFEDIRPATH|SFF_CREAT);
|
||||
|
||||
if (mci->mci_statfile == NULL)
|
||||
{
|
||||
@ -579,19 +628,19 @@ mci_lock_host_statfile(mci)
|
||||
if (!lockfile(fileno(mci->mci_statfile), fname, "", LOCK_EX|LOCK_NB))
|
||||
{
|
||||
if (tTd(56, 2))
|
||||
printf("mci_lock_host: couldn't get lock on %s\n",
|
||||
fname);
|
||||
fclose(mci->mci_statfile);
|
||||
dprintf("mci_lock_host: couldn't get lock on %s\n",
|
||||
fname);
|
||||
(void) fclose(mci->mci_statfile);
|
||||
mci->mci_statfile = NULL;
|
||||
retVal = EX_TEMPFAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (tTd(56, 12) && mci->mci_statfile != NULL)
|
||||
printf("mci_lock_host: Sanity check -- lock is good\n");
|
||||
dprintf("mci_lock_host: Sanity check -- lock is good\n");
|
||||
|
||||
cleanup:
|
||||
errno = savedErrno;
|
||||
errno = save_errno;
|
||||
return retVal;
|
||||
}
|
||||
/*
|
||||
@ -611,12 +660,12 @@ void
|
||||
mci_unlock_host(mci)
|
||||
MCI *mci;
|
||||
{
|
||||
int saveErrno = errno;
|
||||
int save_errno = errno;
|
||||
|
||||
if (mci == NULL)
|
||||
{
|
||||
if (tTd(56, 1))
|
||||
printf("mci_unlock_host: NULL mci\n");
|
||||
dprintf("mci_unlock_host: NULL mci\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -626,23 +675,23 @@ mci_unlock_host(mci)
|
||||
if (!SingleThreadDelivery && mci_lock_host_statfile(mci) == EX_TEMPFAIL)
|
||||
{
|
||||
if (tTd(56, 1))
|
||||
printf("mci_unlock_host: stat file already locked\n");
|
||||
dprintf("mci_unlock_host: stat file already locked\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tTd(56, 2))
|
||||
printf("mci_unlock_host: store prior to unlock\n");
|
||||
dprintf("mci_unlock_host: store prior to unlock\n");
|
||||
|
||||
mci_store_persistent(mci);
|
||||
}
|
||||
|
||||
if (mci->mci_statfile != NULL)
|
||||
{
|
||||
fclose(mci->mci_statfile);
|
||||
(void) fclose(mci->mci_statfile);
|
||||
mci->mci_statfile = NULL;
|
||||
}
|
||||
|
||||
errno = saveErrno;
|
||||
errno = save_errno;
|
||||
}
|
||||
/*
|
||||
** MCI_LOAD_PERSISTENT -- load persistent host info
|
||||
@ -659,38 +708,38 @@ mci_unlock_host(mci)
|
||||
** FALSE -- lock failed
|
||||
*/
|
||||
|
||||
bool
|
||||
static bool
|
||||
mci_load_persistent(mci)
|
||||
MCI *mci;
|
||||
{
|
||||
int saveErrno = errno;
|
||||
int save_errno = errno;
|
||||
bool locked = TRUE;
|
||||
FILE *fp;
|
||||
char fname[MAXPATHLEN+1];
|
||||
char fname[MAXPATHLEN + 1];
|
||||
|
||||
if (mci == NULL)
|
||||
{
|
||||
if (tTd(56, 1))
|
||||
printf("mci_load_persistent: NULL mci\n");
|
||||
dprintf("mci_load_persistent: NULL mci\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (IgnoreHostStatus || HostStatDir == NULL || mci->mci_host == NULL)
|
||||
return TRUE;
|
||||
|
||||
|
||||
/* Already have the persistent information in memory */
|
||||
if (SingleThreadDelivery && mci->mci_statfile != NULL)
|
||||
return TRUE;
|
||||
|
||||
if (tTd(56, 1))
|
||||
printf("mci_load_persistent: Attempting to load persistent information for %s\n",
|
||||
mci->mci_host);
|
||||
|
||||
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)
|
||||
{
|
||||
/* Not much we can do if the file isn't there... */
|
||||
if (tTd(56, 1))
|
||||
printf("mci_load_persistent: Couldn't generate host path\n");
|
||||
dprintf("mci_load_persistent: Couldn't generate host path\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -700,21 +749,23 @@ mci_load_persistent(mci)
|
||||
{
|
||||
/* I can't think of any reason this should ever happen */
|
||||
if (tTd(56, 1))
|
||||
printf("mci_load_persistent: open(%s): %s\n",
|
||||
dprintf("mci_load_persistent: open(%s): %s\n",
|
||||
fname, errstring(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
FileName = fname;
|
||||
locked = lockfile(fileno(fp), fname, "", LOCK_SH|LOCK_NB);
|
||||
(void) mci_read_persistent(fp, mci);
|
||||
FileName = NULL;
|
||||
if (locked)
|
||||
lockfile(fileno(fp), fname, "", LOCK_UN);
|
||||
fclose(fp);
|
||||
{
|
||||
(void) mci_read_persistent(fp, mci);
|
||||
(void) lockfile(fileno(fp), fname, "", LOCK_UN);
|
||||
}
|
||||
FileName = NULL;
|
||||
(void) fclose(fp);
|
||||
|
||||
cleanup:
|
||||
errno = saveErrno;
|
||||
errno = save_errno;
|
||||
return locked;
|
||||
}
|
||||
/*
|
||||
@ -736,7 +787,7 @@ mci_load_persistent(mci)
|
||||
** perfectly safe due to underlying stdio buffering.
|
||||
*/
|
||||
|
||||
int
|
||||
static int
|
||||
mci_read_persistent(fp, mci)
|
||||
FILE *fp;
|
||||
register MCI *mci;
|
||||
@ -752,7 +803,7 @@ mci_read_persistent(fp, mci)
|
||||
syserr("mci_read_persistent: NULL mci");
|
||||
if (tTd(56, 93))
|
||||
{
|
||||
printf("mci_read_persistent: fp=%lx, mci=", (u_long) fp);
|
||||
dprintf("mci_read_persistent: fp=%lx, mci=", (u_long) fp);
|
||||
mci_dump(mci, FALSE);
|
||||
}
|
||||
|
||||
@ -837,12 +888,12 @@ void
|
||||
mci_store_persistent(mci)
|
||||
MCI *mci;
|
||||
{
|
||||
int saveErrno = errno;
|
||||
int save_errno = errno;
|
||||
|
||||
if (mci == NULL)
|
||||
{
|
||||
if (tTd(56, 1))
|
||||
printf("mci_store_persistent: NULL mci\n");
|
||||
dprintf("mci_store_persistent: NULL mci\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -850,20 +901,20 @@ mci_store_persistent(mci)
|
||||
return;
|
||||
|
||||
if (tTd(56, 1))
|
||||
printf("mci_store_persistent: Storing information for %s\n",
|
||||
mci->mci_host);
|
||||
dprintf("mci_store_persistent: Storing information for %s\n",
|
||||
mci->mci_host);
|
||||
|
||||
if (mci->mci_statfile == NULL)
|
||||
{
|
||||
if (tTd(56, 1))
|
||||
printf("mci_store_persistent: no statfile\n");
|
||||
dprintf("mci_store_persistent: no statfile\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rewind(mci->mci_statfile);
|
||||
#if !NOFTRUNCATE
|
||||
(void) ftruncate(fileno(mci->mci_statfile), (off_t) 0);
|
||||
#endif
|
||||
#endif /* !NOFTRUNCATE */
|
||||
|
||||
fprintf(mci->mci_statfile, "V0\n");
|
||||
fprintf(mci->mci_statfile, "E%d\n", mci->mci_errno);
|
||||
@ -878,9 +929,9 @@ mci_store_persistent(mci)
|
||||
fprintf(mci->mci_statfile, "U%ld\n", (long)(mci->mci_lastuse));
|
||||
fprintf(mci->mci_statfile, ".\n");
|
||||
|
||||
fflush(mci->mci_statfile);
|
||||
(void) fflush(mci->mci_statfile);
|
||||
|
||||
errno = saveErrno;
|
||||
errno = save_errno;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -905,6 +956,7 @@ mci_store_persistent(mci)
|
||||
** < 0 -- if any action routine returns a negative value, that
|
||||
** value is returned.
|
||||
** 0 -- if we successfully went to completion.
|
||||
** > 0 -- return status from action()
|
||||
*/
|
||||
|
||||
int
|
||||
@ -922,13 +974,13 @@ mci_traverse_persistent(action, pathname)
|
||||
return -1;
|
||||
|
||||
if (tTd(56, 1))
|
||||
printf("mci_traverse: pathname is %s\n", pathname);
|
||||
dprintf("mci_traverse: pathname is %s\n", pathname);
|
||||
|
||||
ret = stat(pathname, &statbuf);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (tTd(56, 2))
|
||||
printf("mci_traverse: Failed to stat %s: %s\n",
|
||||
dprintf("mci_traverse: Failed to stat %s: %s\n",
|
||||
pathname, errstring(errno));
|
||||
return ret;
|
||||
}
|
||||
@ -936,12 +988,13 @@ mci_traverse_persistent(action, pathname)
|
||||
{
|
||||
struct dirent *e;
|
||||
char *newptr;
|
||||
char newpath[MAXPATHLEN+1];
|
||||
char newpath[MAXPATHLEN + 1];
|
||||
bool leftone, removedone;
|
||||
|
||||
if ((d = opendir(pathname)) == NULL)
|
||||
{
|
||||
if (tTd(56, 2))
|
||||
printf("mci_traverse: opendir %s: %s\n",
|
||||
dprintf("mci_traverse: opendir %s: %s\n",
|
||||
pathname, errstring(errno));
|
||||
return -1;
|
||||
}
|
||||
@ -949,41 +1002,62 @@ mci_traverse_persistent(action, pathname)
|
||||
if (strlen(pathname) >= sizeof newpath - MAXNAMLEN - 3)
|
||||
{
|
||||
if (tTd(56, 2))
|
||||
printf("mci_traverse: path \"%s\" too long",
|
||||
dprintf("mci_traverse: path \"%s\" too long",
|
||||
pathname);
|
||||
return -1;
|
||||
}
|
||||
strcpy(newpath, pathname);
|
||||
(void) strlcpy(newpath, pathname, sizeof newpath);
|
||||
newptr = newpath + strlen(newpath);
|
||||
*newptr++ = '/';
|
||||
|
||||
while ((e = readdir(d)) != NULL)
|
||||
/*
|
||||
** repeat until no file has been removed
|
||||
** this may become ugly when several files "expire"
|
||||
** during these loops, but it's better than doing
|
||||
** a rewinddir() inside the inner loop
|
||||
*/
|
||||
do
|
||||
{
|
||||
if (e->d_name[0] == '.')
|
||||
continue;
|
||||
leftone = removedone = FALSE;
|
||||
while ((e = readdir(d)) != NULL)
|
||||
{
|
||||
if (e->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
strncpy(newptr, e->d_name,
|
||||
sizeof newpath - (newptr - newpath) - 1);
|
||||
newpath[sizeof newpath - 1] = '\0';
|
||||
(void) strlcpy(newptr, e->d_name,
|
||||
sizeof newpath -
|
||||
(newptr - newpath));
|
||||
|
||||
ret = mci_traverse_persistent(action, newpath);
|
||||
ret = mci_traverse_persistent(action, newpath);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret == 1)
|
||||
leftone = TRUE;
|
||||
if (!removedone && ret == 0 &&
|
||||
action == mci_purge_persistent)
|
||||
removedone = TRUE;
|
||||
}
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
** The following appears to be
|
||||
** necessary during purges, since
|
||||
** we modify the directory structure
|
||||
*/
|
||||
|
||||
if (action == mci_purge_persistent)
|
||||
if (removedone)
|
||||
rewinddir(d);
|
||||
}
|
||||
if (tTd(56, 40))
|
||||
dprintf("mci_traverse: path %s: ret %d removed %d left %d\n",
|
||||
pathname, ret, removedone, leftone);
|
||||
} while (removedone);
|
||||
|
||||
/* purge (or whatever) the directory proper */
|
||||
*--newptr = '\0';
|
||||
ret = (*action)(newpath, NULL);
|
||||
closedir(d);
|
||||
if (!leftone)
|
||||
{
|
||||
*--newptr = '\0';
|
||||
ret = (*action)(newpath, NULL);
|
||||
}
|
||||
(void) closedir(d);
|
||||
}
|
||||
else if (S_ISREG(statbuf.st_mode))
|
||||
{
|
||||
@ -992,7 +1066,7 @@ mci_traverse_persistent(action, pathname)
|
||||
char *scan;
|
||||
char host[MAXHOSTNAMELEN];
|
||||
char *hostptr = host;
|
||||
|
||||
|
||||
/*
|
||||
** Reconstruct the host name from the path to the
|
||||
** persistent information.
|
||||
@ -1027,7 +1101,7 @@ mci_traverse_persistent(action, pathname)
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
** MCI_PRINT_PERSISTENT -- print persisten info
|
||||
** MCI_PRINT_PERSISTENT -- print persistent info
|
||||
**
|
||||
** Dump the persistent information in the file 'pathname'
|
||||
**
|
||||
@ -1066,23 +1140,23 @@ mci_print_persistent(pathname, hostname)
|
||||
if (fp == NULL)
|
||||
{
|
||||
if (tTd(56, 1))
|
||||
printf("mci_print_persistent: cannot open %s: %s\n",
|
||||
dprintf("mci_print_persistent: cannot open %s: %s\n",
|
||||
pathname, errstring(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
FileName = pathname;
|
||||
bzero(&mcib, sizeof mcib);
|
||||
memset(&mcib, '\0', sizeof mcib);
|
||||
if (mci_read_persistent(fp, &mcib) < 0)
|
||||
{
|
||||
syserr("%s: could not read status file", pathname);
|
||||
fclose(fp);
|
||||
(void) fclose(fp);
|
||||
FileName = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
locked = !lockfile(fileno(fp), pathname, "", LOCK_EX|LOCK_NB);
|
||||
fclose(fp);
|
||||
(void) fclose(fp);
|
||||
FileName = NULL;
|
||||
|
||||
printf("%c%-39s %12s ",
|
||||
@ -1125,7 +1199,9 @@ mci_print_persistent(pathname, hostname)
|
||||
** NULL if this is a directory (domain).
|
||||
**
|
||||
** Returns:
|
||||
** 0
|
||||
** 0 -- ok
|
||||
** 1 -- file not deleted (too young, incorrect format)
|
||||
** < 0 -- some error occurred
|
||||
*/
|
||||
|
||||
int
|
||||
@ -1133,18 +1209,30 @@ mci_purge_persistent(pathname, hostname)
|
||||
char *pathname;
|
||||
char *hostname;
|
||||
{
|
||||
struct stat statbuf;
|
||||
char *end = pathname + strlen(pathname) - 1;
|
||||
int ret;
|
||||
|
||||
if (tTd(56, 1))
|
||||
printf("mci_purge_persistent: purging %s\n", pathname);
|
||||
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));
|
||||
return ret;
|
||||
}
|
||||
if (curtime() - statbuf.st_mtime < MciInfoTimeout)
|
||||
return 1;
|
||||
if (hostname != NULL)
|
||||
{
|
||||
/* remove the file */
|
||||
if (unlink(pathname) < 0)
|
||||
{
|
||||
if (tTd(56, 2))
|
||||
printf("mci_purge_persistent: failed to unlink %s: %s\n",
|
||||
dprintf("mci_purge_persistent: failed to unlink %s: %s\n",
|
||||
pathname, errstring(errno));
|
||||
}
|
||||
}
|
||||
@ -1152,18 +1240,18 @@ mci_purge_persistent(pathname, hostname)
|
||||
{
|
||||
/* remove the directory */
|
||||
if (*end != '.')
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
if (tTd(56, 1))
|
||||
printf("mci_purge_persistent: dpurge %s\n", pathname);
|
||||
dprintf("mci_purge_persistent: dpurge %s\n", pathname);
|
||||
|
||||
if (rmdir(pathname) < 0)
|
||||
{
|
||||
if (tTd(56, 2))
|
||||
printf("mci_purge_persistent: rmdir %s: %s\n",
|
||||
dprintf("mci_purge_persistent: rmdir %s: %s\n",
|
||||
pathname, errstring(errno));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1187,7 +1275,7 @@ mci_purge_persistent(pathname, hostname)
|
||||
** -1 -- failure
|
||||
*/
|
||||
|
||||
int
|
||||
static int
|
||||
mci_generate_persistent_path(host, path, pathlen, createflag)
|
||||
const char *host;
|
||||
char *path;
|
||||
@ -1198,6 +1286,9 @@ mci_generate_persistent_path(host, path, pathlen, createflag)
|
||||
int ret = 0;
|
||||
int len;
|
||||
char t_host[MAXHOSTNAMELEN];
|
||||
#if NETINET6
|
||||
struct in6_addr in6_addr;
|
||||
#endif /* NETINET6 */
|
||||
|
||||
/*
|
||||
** Rationality check the arguments.
|
||||
@ -1215,7 +1306,7 @@ mci_generate_persistent_path(host, path, pathlen, createflag)
|
||||
}
|
||||
|
||||
if (tTd(56, 80))
|
||||
printf("mci_generate_persistent_path(%s): ", host);
|
||||
dprintf("mci_generate_persistent_path(%s): ", host);
|
||||
|
||||
if (*host == '\0' || *host == '.')
|
||||
return -1;
|
||||
@ -1224,9 +1315,9 @@ mci_generate_persistent_path(host, path, pathlen, createflag)
|
||||
if (strlen(host) > sizeof t_host - 1)
|
||||
return -1;
|
||||
if (host[0] == '[')
|
||||
strcpy(t_host, host + 1);
|
||||
else
|
||||
strcpy(t_host, host);
|
||||
(void) strlcpy(t_host, host + 1, sizeof t_host);
|
||||
else
|
||||
(void) strlcpy(t_host, host, sizeof t_host);
|
||||
|
||||
/*
|
||||
** Delete any trailing dots from the hostname.
|
||||
@ -1238,9 +1329,18 @@ 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] == '[' && inet_addr(t_host) == INADDR_NONE)
|
||||
if (host[0] == '[' &&
|
||||
# if NETINET6
|
||||
inet_pton(AF_INET6, t_host, &in6_addr) != 1 &&
|
||||
# endif /* NETINET6 */
|
||||
# if NETINET
|
||||
inet_addr(t_host) == INADDR_NONE
|
||||
# endif /* NETINET */
|
||||
)
|
||||
return -1;
|
||||
#endif /* NETINET || NETINET6 */
|
||||
|
||||
/* check for what will be the final length of the path */
|
||||
len = strlen(HostStatDir) + 2;
|
||||
@ -1255,7 +1355,7 @@ mci_generate_persistent_path(host, path, pathlen, createflag)
|
||||
if (len > pathlen || len < 1)
|
||||
return -1;
|
||||
|
||||
strcpy(path, HostStatDir);
|
||||
(void) strlcpy(path, HostStatDir, pathlen);
|
||||
p = path + strlen(path);
|
||||
|
||||
while (elem > t_host)
|
||||
@ -1286,10 +1386,10 @@ mci_generate_persistent_path(host, path, pathlen, createflag)
|
||||
if (tTd(56, 80))
|
||||
{
|
||||
if (ret < 0)
|
||||
printf("FAILURE %d\n", ret);
|
||||
dprintf("FAILURE %d\n", ret);
|
||||
else
|
||||
printf("SUCCESS %s\n", path);
|
||||
dprintf("SUCCESS %s\n", path);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
return ret;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user