xref: /csrg-svn/usr.sbin/sendmail/src/err.c (revision 14900)
13311Seric # include "sendmail.h"
2295Seric 
3*14900Seric SCCSID(@(#)err.c	4.2		09/05/83);
4406Seric 
5295Seric /*
61514Seric **  SYSERR -- Print error message.
7295Seric **
8295Seric **	Prints an error message via printf to the diagnostic
9295Seric **	output.  If LOG is defined, it logs it also.
10295Seric **
11295Seric **	Parameters:
12295Seric **		f -- the format string
13295Seric **		a, b, c, d, e -- parameters
14295Seric **
15295Seric **	Returns:
164084Seric **		none
177762Seric **		Through TopFrame if QuickAbort is set.
18295Seric **
19295Seric **	Side Effects:
201514Seric **		increments Errors.
211514Seric **		sets ExitStat.
22295Seric */
23295Seric 
244084Seric # ifdef lint
254084Seric int	sys_nerr;
264084Seric char	*sys_errlist[];
274084Seric # endif lint
2810147Seric char	MsgBuf[BUFSIZ*2];	/* text of most recent message */
294084Seric 
30295Seric /*VARARGS1*/
31295Seric syserr(fmt, a, b, c, d, e)
32295Seric 	char *fmt;
33295Seric {
347957Seric 	extern char Arpa_PSyserr[];
357957Seric 	extern char Arpa_TSyserr[];
367957Seric 	register char *p;
37295Seric 
387525Seric 	/* format and output the error message */
397957Seric 	if (errno == 0)
407957Seric 		p = Arpa_PSyserr;
417957Seric 	else
427957Seric 		p = Arpa_TSyserr;
437957Seric 	fmtmsg(MsgBuf, (char *) NULL, p, fmt, a, b, c, d, e);
449389Seric 	puterrmsg(MsgBuf);
454063Seric 
46295Seric 	/* determine exit status if not already set */
47295Seric 	if (ExitStat == EX_OK)
48295Seric 	{
49295Seric 		if (errno == 0)
50295Seric 			ExitStat = EX_SOFTWARE;
51295Seric 		else
521598Seric 			ExitStat = EX_OSERR;
53295Seric 	}
54295Seric 
559372Seric 	/* insure that we have a queue id for logging */
567810Seric 	(void) queuename(CurEnv, '\0');
57295Seric # ifdef LOG
587674Seric 	if (LogLevel > 0)
5910050Seric 		syslog(LOG_ERR, "%s: SYSERR: %s", CurEnv->e_id, &MsgBuf[4]);
60295Seric # endif LOG
61295Seric 	errno = 0;
627762Seric 	if (QuickAbort)
637762Seric 		longjmp(TopFrame, 2);
64295Seric }
65295Seric /*
66295Seric **  USRERR -- Signal user error.
67295Seric **
68295Seric **	This is much like syserr except it is for user errors.
69295Seric **
70295Seric **	Parameters:
71295Seric **		fmt, a, b, c, d -- printf strings
72295Seric **
73295Seric **	Returns:
744084Seric **		none
757762Seric **		Through TopFrame if QuickAbort is set.
76295Seric **
77295Seric **	Side Effects:
781514Seric **		increments Errors.
79295Seric */
80295Seric 
81295Seric /*VARARGS1*/
82295Seric usrerr(fmt, a, b, c, d, e)
83295Seric 	char *fmt;
84295Seric {
85295Seric 	extern char SuprErrs;
864167Seric 	extern char Arpa_Usrerr[];
87295Seric 
88295Seric 	if (SuprErrs)
894084Seric 		return;
90295Seric 
917613Seric 	fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, fmt, a, b, c, d, e);
929389Seric 	puterrmsg(MsgBuf);
938239Seric 
947762Seric 	if (QuickAbort)
957762Seric 		longjmp(TopFrame, 1);
964063Seric }
974063Seric /*
984063Seric **  MESSAGE -- print message (not necessarily an error)
994063Seric **
1004063Seric **	Parameters:
1014063Seric **		num -- the default ARPANET error number (in ascii)
1024063Seric **		msg -- the message (printf fmt) -- if it begins
1034063Seric **			with a digit, this number overrides num.
1044063Seric **		a, b, c, d, e -- printf arguments
1054063Seric **
1064063Seric **	Returns:
1074063Seric **		none
1084063Seric **
1094063Seric **	Side Effects:
1104063Seric **		none.
1114063Seric */
1124063Seric 
1134084Seric /*VARARGS2*/
1144063Seric message(num, msg, a, b, c, d, e)
1154063Seric 	register char *num;
1164063Seric 	register char *msg;
1174063Seric {
1184711Seric 	errno = 0;
1197525Seric 	fmtmsg(MsgBuf, CurEnv->e_to, num, msg, a, b, c, d, e);
1209108Seric 	putmsg(MsgBuf, FALSE);
1217613Seric }
1227613Seric /*
1238239Seric **  NMESSAGE -- print message (not necessarily an error)
1248239Seric **
1258239Seric **	Just like "message" except it never puts the to... tag on.
1268239Seric **
1278239Seric **	Parameters:
1288239Seric **		num -- the default ARPANET error number (in ascii)
1298239Seric **		msg -- the message (printf fmt) -- if it begins
1308239Seric **			with a digit, this number overrides num.
1318239Seric **		a, b, c, d, e -- printf arguments
1328239Seric **
1338239Seric **	Returns:
1348239Seric **		none
1358239Seric **
1368239Seric **	Side Effects:
1378239Seric **		none.
1388239Seric */
1398239Seric 
1408239Seric /*VARARGS2*/
1418239Seric nmessage(num, msg, a, b, c, d, e)
1428239Seric 	register char *num;
1438239Seric 	register char *msg;
1448239Seric {
1458239Seric 	errno = 0;
1469346Seric 	fmtmsg(MsgBuf, (char *) NULL, num, msg, a, b, c, d, e);
1479108Seric 	putmsg(MsgBuf, FALSE);
1488239Seric }
1498239Seric /*
1507613Seric **  PUTMSG -- output error message to transcript and channel
1517613Seric **
1527613Seric **	Parameters:
1537613Seric **		msg -- message to output (in SMTP format).
1549108Seric **		holdmsg -- if TRUE, don't output a copy of the message to
1559108Seric **			our output channel.
1567613Seric **
1577613Seric **	Returns:
1587613Seric **		none.
1597613Seric **
1607613Seric **	Side Effects:
1617613Seric **		Outputs msg to the transcript.
1627613Seric **		If appropriate, outputs it to the channel.
1637613Seric **		Deletes SMTP reply code number as appropriate.
1647613Seric */
1654711Seric 
1669108Seric putmsg(msg, holdmsg)
1677613Seric 	char *msg;
1689108Seric 	bool holdmsg;
1697613Seric {
170*14900Seric 	/* output to transcript if serious */
171*14900Seric 	if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5'))
172*14900Seric 		fprintf(CurEnv->e_xfp, "%s\n", msg);
1734711Seric 
1744711Seric 	/* output to channel if appropriate */
1759108Seric 	if (!holdmsg && (Verbose || msg[0] != '0'))
1764063Seric 	{
1777275Seric 		(void) fflush(stdout);
1789277Seric 		if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
1797613Seric 			fprintf(OutChannel, "%s\r\n", msg);
1804711Seric 		else
1817613Seric 			fprintf(OutChannel, "%s\n", &msg[4]);
1824711Seric 		(void) fflush(OutChannel);
1834063Seric 	}
1849389Seric }
1859389Seric /*
1869389Seric **  PUTERRMSG -- like putmsg, but does special processing for error messages
1879389Seric **
1889389Seric **	Parameters:
1899389Seric **		msg -- the message to output.
1909389Seric **
1919389Seric **	Returns:
1929389Seric **		none.
1939389Seric **
1949389Seric **	Side Effects:
1959389Seric **		Sets the fatal error bit in the envelope as appropriate.
1969389Seric */
1978239Seric 
1989389Seric puterrmsg(msg)
1999389Seric 	char *msg;
2009389Seric {
2019389Seric 	/* output the message as usual */
2029389Seric 	putmsg(msg, HoldErrs);
2039389Seric 
2049389Seric 	/* signal the error */
2059389Seric 	Errors++;
2069389Seric 	if (msg[0] == '5')
2079336Seric 		CurEnv->e_flags |= EF_FATALERRS;
2084711Seric }
2094711Seric /*
2104711Seric **  FMTMSG -- format a message into buffer.
2114711Seric **
2124711Seric **	Parameters:
2134711Seric **		eb -- error buffer to get result.
2144711Seric **		to -- the recipient tag for this message.
2154711Seric **		num -- arpanet error number.
2164711Seric **		fmt -- format of string.
2174711Seric **		a, b, c, d, e -- arguments.
2184711Seric **
2194711Seric **	Returns:
2204711Seric **		none.
2214711Seric **
2224711Seric **	Side Effects:
2234711Seric **		none.
2244711Seric */
2254063Seric 
2264834Seric /*VARARGS4*/
2274711Seric static
2284711Seric fmtmsg(eb, to, num, fmt, a, b, c, d, e)
2294711Seric 	register char *eb;
2304711Seric 	char *to;
2314711Seric 	char *num;
2324711Seric 	char *fmt;
2334711Seric {
2344711Seric 	char del;
2354711Seric 
2364711Seric 	/* output the reply code */
2374711Seric 	if (isdigit(*fmt))
2384577Seric 	{
2394711Seric 		num = fmt;
2404711Seric 		fmt += 4;
2414711Seric 	}
2424711Seric 	if (num[3] == '-')
2434711Seric 		del = '-';
2444711Seric 	else
2454711Seric 		del = ' ';
2464711Seric 	(void) sprintf(eb, "%3.3s%c", num, del);
2474711Seric 	eb += 4;
2484063Seric 
2499372Seric 	/* output the file name and line number */
2509372Seric 	if (FileName != NULL)
2519372Seric 	{
2529372Seric 		(void) sprintf(eb, "%s: line %d: ", FileName, LineNumber);
2539372Seric 		eb += strlen(eb);
2549372Seric 	}
2559372Seric 
2564711Seric 	/* output the "to" person */
2574711Seric 	if (to != NULL && to[0] != '\0')
2584711Seric 	{
2594711Seric 		(void) sprintf(eb, "%s... ", to);
2605201Seric 		while (*eb != '\0')
2615201Seric 			*eb++ &= 0177;
2624711Seric 	}
2634711Seric 
2644711Seric 	/* output the message */
2654711Seric 	(void) sprintf(eb, fmt, a, b, c, d, e);
2665201Seric 	while (*eb != '\0')
2675201Seric 		*eb++ &= 0177;
2684711Seric 
2694711Seric 	/* output the error code, if any */
2704711Seric 	if (errno != 0)
2714711Seric 	{
2724711Seric 		extern int sys_nerr;
2734711Seric 		extern char *sys_errlist[];
2744711Seric 		if (errno < sys_nerr && errno > 0)
2754711Seric 			(void) sprintf(eb, ": %s", sys_errlist[errno]);
2764577Seric 		else
2774711Seric 			(void) sprintf(eb, ": error %d", errno);
2784711Seric 		eb += strlen(eb);
2794577Seric 	}
280295Seric }
281