02ea9bb533e835ae9e153738a574de534877fa48
* Copyright (c) 1983 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)err.c 8.28 (Berkeley) %G%";
** SYSERR -- Print error message.
** Prints an error message via printf to the diagnostic
** output. If LOG is defined, it logs it also.
** If the first character of the syserr message is `!' it will
** log this as an ALERT message and exit immediately. This can
** leave queue files in an indeterminate state, so it should not
** f -- the format string
** a, b, c, d, e -- parameters
** Through TopFrame if QuickAbort is set.
char MsgBuf
[BUFSIZ
*2]; /* text of most recent message */
#if NAMED_BIND && !defined(NO_DATA)
# define NO_DATA NO_ADDRESS
syserr(const char *fmt
, ...)
/* format and output the error message */
fmtmsg(MsgBuf
, (char *) NULL
, p
, olderrno
, fmt
, ap
);
/* determine exit status if not already set */
printf("syserr: ExitStat = %d\n", ExitStat
);
sprintf(ubuf
, "UID%d", getuid());
syslog(panic
? LOG_ALERT
: LOG_CRIT
, "%s: SYSERR(%s): %s",
CurEnv
->e_id
== NULL
? "NOQUEUE" : CurEnv
->e_id
,
** USRERR -- Signal user error.
** This is much like syserr except it is for user errors.
** fmt, a, b, c, d -- printf strings
** Through TopFrame if QuickAbort is set.
usrerr(const char *fmt
, ...)
fmtmsg(MsgBuf
, CurEnv
->e_to
, "501", 0, fmt
, ap
);
if (LogLevel
> 3 && LogUsrErrs
)
syslog(LOG_NOTICE
, "%s: %s",
CurEnv
->e_id
== NULL
? "NOQUEUE" : CurEnv
->e_id
,
** MESSAGE -- print message (not necessarily an error)
** msg -- the message (printf fmt) -- it can begin with
** an SMTP reply code. If not, 050 is assumed.
** a, b, c, d, e -- printf arguments
message(const char *msg
, ...)
fmtmsg(MsgBuf
, CurEnv
->e_to
, "050", 0, msg
, ap
);
putoutmsg(MsgBuf
, FALSE
);
** NMESSAGE -- print message (not necessarily an error)
** Just like "message" except it never puts the to... tag on.
** num -- the default ARPANET error number (in ascii)
** msg -- the message (printf fmt) -- if it begins
** with three digits, this number overrides num.
** a, b, c, d, e -- printf arguments
nmessage(const char *msg
, ...)
fmtmsg(MsgBuf
, (char *) NULL
, "050", 0, msg
, ap
);
putoutmsg(MsgBuf
, FALSE
);
** PUTOUTMSG -- output error message to transcript and channel
** msg -- message to output (in SMTP format).
** holdmsg -- if TRUE, don't output a copy of the message to
** Outputs msg to the transcript.
** If appropriate, outputs it to the channel.
** Deletes SMTP reply code number as appropriate.
/* display for debugging */
printf("--- %s%s\n", msg
, holdmsg
? " (held)" : "");
/* output to transcript if serious */
if (CurEnv
->e_xfp
!= NULL
&& strchr("456", msg
[0]) != NULL
)
fprintf(CurEnv
->e_xfp
, "%s\n", msg
);
/* output to channel if appropriate */
if (holdmsg
|| (!Verbose
&& msg
[0] == '0'))
/* map warnings to something SMTP can handle */
/* if DisConnected, OutChannel now points to the transcript */
(OpMode
== MD_SMTP
|| OpMode
== MD_DAEMON
|| OpMode
== MD_ARPAFTP
))
fprintf(OutChannel
, "%s\r\n", msg
);
fprintf(OutChannel
, "%s\n", &msg
[4]);
if (TrafficLogFile
!= NULL
)
fprintf(TrafficLogFile
, "%05d >>> %s\n", getpid(),
(OpMode
== MD_SMTP
|| OpMode
== MD_DAEMON
) ? msg
: &msg
[4]);
(void) fflush(OutChannel
);
if (!ferror(OutChannel
) || DisConnected
)
** Error on output -- if reporting lost channel, just ignore it.
** Also, ignore errors from QUIT response (221 message) -- some
** rude servers don't read result.
if (feof(InChannel
) || ferror(InChannel
) || strncmp(msg
, "221", 3) == 0)
/* can't call syserr, 'cause we are using MsgBuf */
"%s: SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s",
CurEnv
->e_id
== NULL
? "NOQUEUE" : CurEnv
->e_id
,
CurHostName
== NULL
? "NO-HOST" : CurHostName
,
** PUTERRMSG -- like putoutmsg, but does special processing for error messages
** msg -- the message to output.
** Sets the fatal error bit in the envelope as appropriate.
/* output the message as usual */
putoutmsg(msg
, HoldErrs
);
/* notify the postmaster */
CurEnv
->e_flags
|= EF_PM_NOTIFY
;
else if ((msgcode
== '4' || msgcode
== '5') &&
bitset(EF_GLOBALERRS
, CurEnv
->e_flags
))
/* mark long-term fatal errors */
CurEnv
->e_flags
|= EF_FATALERRS
;
** FMTMSG -- format a message into buffer.
** eb -- error buffer to get result.
** to -- the recipient tag for this message.
** num -- arpanet error number.
** en -- the error number to display.
** fmt -- format of string.
** a, b, c, d, e -- arguments.
fmtmsg(eb
, to
, num
, eno
, fmt
, ap
)
/* output the reply code */
if (isdigit(fmt
[0]) && isdigit(fmt
[1]) && isdigit(fmt
[2]))
(void) sprintf(eb
, "%3.3s%c", num
, del
);
/* output the file name and line number */
(void) sprintf(eb
, "%s: line %d: ", FileName
, LineNumber
);
/* output the "to" person */
if (to
!= NULL
&& to
[0] != '\0')
(void) sprintf(eb
, "%s... ", shortenstring(to
, 203));
(void) vsprintf(eb
, fmt
, ap
);
/* output the error code, if any */
(void) sprintf(eb
, ": %s", errstring(eno
));
if (num
[0] == '5' || (CurEnv
->e_message
== NULL
&& num
[0] == '4'))
if (CurEnv
->e_message
!= NULL
)
CurEnv
->e_message
= newstr(meb
);
** ERRSTRING -- return string description of error code
** errnum -- the error number to translate
** A string description of errnum.
static char buf
[MAXLINE
];
# ifndef ERRLIST_PREDEFINED
extern char *sys_errlist
[];
** Handle special network error codes.
** These are 4.2/4.3bsd specific; they should be in daemon.c.
# if defined(DAEMON) && defined(ETIMEDOUT)
(void) strcpy(buf
, sys_errlist
[errnum
]);
(void) strcat(buf
, " during ");
(void) strcat(buf
, SmtpPhase
);
(void) strcat(buf
, " with ");
(void) strcat(buf
, CurHostName
);
(void) sprintf(buf
, "Host %s is down", CurHostName
);
(void) sprintf(buf
, "Connection refused by %s", CurHostName
);
return "Timeout on file open";
case HOST_NOT_FOUND
+ E_DNSBASE
:
dnsmsg
= "host not found";
case TRY_AGAIN
+ E_DNSBASE
:
dnsmsg
= "host name lookup failure";
case NO_RECOVERY
+ E_DNSBASE
:
dnsmsg
= "non-recoverable error";
case NO_DATA
+ E_DNSBASE
:
dnsmsg
= "no data known";
/* SunOS gives "Not owner" -- this is the POSIX message */
return "Operation not permitted";
(void) strcpy(buf
, "Name server: ");
(void) strcat(buf
, CurHostName
);
(void) strcat(buf
, ": ");
(void) strcat(buf
, dnsmsg
);
if (errnum
> 0 && errnum
< sys_nerr
)
return (sys_errlist
[errnum
]);
(void) sprintf(buf
, "Error %d", errnum
);