1N/A * Copyright (c) 1998-2003, 2010 Sendmail, Inc. and its suppliers. 1N/A * All rights reserved. 1N/A * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 1N/A * Copyright (c) 1988, 1993 1N/A * The Regents of the University of California. All rights reserved. 1N/A * By using this file, you agree to the terms and conditions set 1N/A * forth in the LICENSE file which can be found at the top level of 1N/A * the sendmail distribution. 1N/Astatic char *
fmtmsg __P((
char *,
const char *,
const char *,
const char *,
1N/A** FATAL_ERROR -- handle a fatal exception 1N/A** This function is installed as the default exception handler 1N/A** in the main sendmail process, and in all child processes 1N/A** that we create. Its job is to handle exceptions that are not 1N/A** handled at a lower level. 1N/A** The theory is that unhandled exceptions will be 'fatal' class 1N/A** exceptions (with an "F:" prefix), such as the out-of-memory 1N/A** exception "F:sm.heap". As such, they are handled by exiting 1N/A** the process in exactly the same way that xalloc() in Sendmail 8.10 1N/A** exits the process when it fails due to lack of memory: 1N/A** we call syserr with a message beginning with "!". 1N/A** exc -- exception which is terminating this process 1N/A ** This function may be called when the heap is exhausted. 1N/A ** The following code writes the message for 'exc' into our 1N/A ** static buffer without allocating memory or raising exceptions. 1N/A ** Terminate the process after logging an error and cleaning up. 1N/A ** - syserr decides what class of error this is by looking at errno. 1N/A ** That's no good; we should look at the exc structure. 1N/A ** - The cleanup code should be moved out of syserr 1N/A ** and into individual exception handlers 1N/A ** that are part of the module they clean up after. 1N/A** SYSERR -- Print error message. 1N/A** Prints an error message via sm_io_printf to the diagnostic output. 1N/A** If the first character of the syserr message is `!' it will 1N/A** log this as an ALERT message and exit immediately. This can 1N/A** leave queue files in an indeterminate state, so it should not 1N/A** If the first character of the syserr message is '!' or '@' 1N/A** then syserr knows that the process is about to be terminated, 1N/A** so the SMTP reply code defaults to 421. Otherwise, the 1N/A** reply code defaults to 451 or 554, depending on errno. 1N/A** fmt -- the format string. An optional '!' or '@', 1N/A** followed by an optional three-digit SMTP 1N/A** reply code, followed by message text. 1N/A** (others) -- parameters 1N/A** Raises E:mta.quickabort if QuickAbort is set. 1N/A** increments Errors. 1N/A#
endif /* NAMED_BIND && !defined(NO_DATA) */ 1N/A#
endif /* __STDC__ */ 1N/A /* format and output the error message */ 1N/A ** Since we are terminating the process, 1N/A ** we are aborting the entire SMTP session, 1N/A ** rather than just the current transaction. 1N/A /* save this message for mailq printing */ 1N/A /* determine exit status if not already set */ 1N/A "SYSERR(%s): %.900s",
1N/A** USRERR -- Signal user error. 1N/A** This is much like syserr except it is for user errors. 1N/A** fmt -- the format string. If it does not begin with 1N/A** a three-digit SMTP reply code, 550 is assumed. 1N/A** (others) -- sm_io_printf strings 1N/A** Raises E:mta.quickabort if QuickAbort is set. 1N/A** increments Errors. 1N/A#
endif /* __STDC__ */ 1N/A /* save this message for mailq printing */ 1N/A "Postmaster warning: %.*s",
1N/A** USRERRENH -- Signal user error. 1N/A** Same as usrerr but with enhanced status code. 1N/A** enhsc -- the enhanced status code. 1N/A** fmt -- the format string. If it does not begin with 1N/A** a three-digit SMTP reply code, 550 is assumed. 1N/A** (others) -- sm_io_printf strings 1N/A** Raises E:mta.quickabort if QuickAbort is set. 1N/A** increments Errors. 1N/A#
endif /* __STDC__ */ 1N/A /* save this message for mailq printing */ 1N/A "Postmaster warning: %.*s",
1N/A** MESSAGE -- print message (not necessarily an error) 1N/A** msg -- the message (sm_io_printf fmt) -- it can begin with 1N/A** an SMTP reply code. If not, 050 is assumed. 1N/A** (others) -- sm_io_printf arguments 1N/A#
endif /* __STDC__ */ 1N/A /* save this message for mailq printing */ 1N/A** NMESSAGE -- print message (not necessarily an error) 1N/A** Just like "message" except it never puts the to... tag on. 1N/A** msg -- the message (sm_io_printf fmt) -- if it begins 1N/A** with a three digit SMTP reply code, that is used, 1N/A** otherwise 050 is assumed. 1N/A** (others) -- sm_io_printf arguments 1N/A#
endif /* __STDC__ */ 1N/A /* save this message for mailq printing */ 1N/A** PUTOUTMSG -- output error message to transcript and channel 1N/A** msg -- message to output (in SMTP format). 1N/A** holdmsg -- if true, don't output a copy of the message to 1N/A** our output channel. 1N/A** heldmsg -- if true, this is a previously held message; 1N/A** don't log it to the transcript file. 1N/A** Outputs msg to the transcript. 1N/A** If appropriate, outputs it to the channel. 1N/A** Deletes SMTP reply code number as appropriate. 1N/A /* display for debugging */ 1N/A /* map warnings to something SMTP can handle */ 1N/A /* output to transcript if serious */ 1N/A /* output to channel if appropriate */ 1N/A /* save for possible future display */ 1N/A /* find actual text of error (after SMTP status codes) */ 1N/A /* if DisConnected, OutChannel now points to the transcript */ 1N/A /* XXX can't flush here for SMTP pipelining */ 1N/A ** Error on output -- if reporting lost channel, just ignore it. 1N/A ** Also, ignore errors from QUIT response (221 message) -- some 1N/A ** rude servers don't read result. 1N/A /* can't call syserr, 'cause we are using MsgBuf */ 1N/A "SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s",
1N/A#
endif /* !PIPELINING */ 1N/A** PUTERRMSG -- like putoutmsg, but does special processing for error messages 1N/A** msg -- the message to output. 1N/A** Sets the fatal error bit in the envelope as appropriate. 1N/A /* output the message as usual */ 1N/A /* be careful about multiple error messages */ 1N/A /* signal the error */ 1N/A /* notify the postmaster */ 1N/A /* mark long-term fatal errors */ 1N/A** ISENHSC -- check whether a string contains an enhanced status code 1N/A** s -- string with possible enhanced status code. 1N/A** delim -- delim for enhanced status code. 1N/A** 0 -- no enhanced status code. 1N/A** >4 -- length of enhanced status code. 1N/A if (!((*s ==
'2' || *s ==
'4' || *s ==
'5') && s[
1] ==
'.'))
1N/A if (h == 0 || s[l + h] !=
'.')
1N/A** EXTENHSC -- check and extract an enhanced status code 1N/A** s -- string with possible enhanced status code. 1N/A** delim -- delim for enhanced status code. 1N/A** e -- pointer to storage for enhanced status code. 1N/A** must be != NULL and have space for at least 1N/A** 10 characters ([245].[0-9]{1,3}.[0-9]{1,3}) 1N/A** 0 -- no enhanced status code. 1N/A** >4 -- length of enhanced status code. 1N/A** fills e with enhanced status code. 1N/A if (!((*s ==
'2' || *s ==
'4' || *s ==
'5') && s[
1] ==
'.'))
1N/A e[l + h] = s[l + h];
1N/A if (h == 0 || s[l + h] !=
'.')
1N/A e[l + h] = s[l + h];
1N/A** FMTMSG -- format a message into buffer. 1N/A** eb -- error buffer to get result -- MUST BE MsgBuf. 1N/A** to -- the recipient tag for this message. 1N/A** num -- default three digit SMTP reply code. 1N/A** enhsc -- enhanced status code. 1N/A** en -- the error number to display. 1N/A** fmt -- format of string. 1N/A** ap -- arguments for fmt. 1N/A** pointer to error text beyond status codes. 1N/A /* output the reply code */ 1N/A /* replace 5 by 4 */ 1N/A /* copy enh.status code including trailing blank */ 1N/A /* replace 5 by 4 */ 1N/A /* output the file name and line number */ 1N/A ** output the "to" address only if it is defined and one of the 1N/A ** following codes is used: 1N/A ** 050 internal notices, e.g., alias expansion 1N/A ** 252 Cannot VRFY user, but will accept message and attempt delivery 1N/A ** 450 Requested mail action not taken: mailbox unavailable 1N/A ** 550 Requested action not taken: mailbox unavailable 1N/A ** 553 Requested action not taken: mailbox name not allowed 1N/A ** Notice: this still isn't "the right thing", this code shouldn't 1N/A ** (indirectly) depend on CurEnv->e_to. 1N/A /* output the message */ 1N/A /* output the error code, if any */ 1N/A** BUFFER_ERRORS -- arrange to buffer future error messages 1N/A** FLUSH_ERRORS -- flush the held error message buffer 1N/A** print -- if set, print the message, otherwise just 1N/A** SM_ERRSTRING -- return string description of error code 1N/A** errnum -- the error number to translate 1N/A** A string description of errnum. 1N/A#
endif /* HASSTRERROR */ 1N/A#
endif /* !HASSTRERROR && !defined(ERRLIST_PREDEFINED) */ 1N/A ** Handle special network error codes. 1N/A ** These are 4.2/4.3bsd specific; they should be in daemon.c. 1N/A#
else /* HASSTRERROR */ 1N/A#
endif /* HASSTRERROR */ 1N/A "Connection reset by ");
1N/A#
endif /* NAMED_BIND */ 1N/A /* SunOS gives "Not owner" -- this is the POSIX message */ 1N/A return "Operation not permitted";
1N/A ** Error messages used internally in sendmail. 1N/A return "Timeout on file open";
1N/A return "Symbolic links not allowed";
1N/A return "Hard links not allowed";
1N/A return "Regular files only";
1N/A return "Executable files not allowed";
1N/A return "World writable directory";
1N/A return "Group writable directory";
1N/A return "File changed after open";
1N/A return "World writable file";
1N/A return "Group writable file";
1N/A return "Group readable file";
1N/A return "World readable file";
1N/A#
else /* HASSTRERROR */ 1N/A#
endif /* HASSTRERROR */