xref: /csrg-svn/usr.sbin/sendmail/src/err.c (revision 16901)
13311Seric # include "sendmail.h"
2295Seric 
3*16901Seric SCCSID(@(#)err.c	4.4		08/11/84);
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 {
34*16901Seric 	register char *p;
35*16901Seric 	int olderrno = errno;
367957Seric 	extern char Arpa_PSyserr[];
377957Seric 	extern char Arpa_TSyserr[];
38295Seric 
397525Seric 	/* format and output the error message */
40*16901Seric 	if (olderrno == 0)
417957Seric 		p = Arpa_PSyserr;
427957Seric 	else
437957Seric 		p = Arpa_TSyserr;
44*16901Seric 	fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, a, b, c, d, e);
459389Seric 	puterrmsg(MsgBuf);
464063Seric 
47295Seric 	/* determine exit status if not already set */
48295Seric 	if (ExitStat == EX_OK)
49295Seric 	{
50*16901Seric 		if (olderrno == 0)
51295Seric 			ExitStat = EX_SOFTWARE;
52295Seric 		else
531598Seric 			ExitStat = EX_OSERR;
54295Seric 	}
55295Seric 
569372Seric 	/* insure that we have a queue id for logging */
577810Seric 	(void) queuename(CurEnv, '\0');
58295Seric # ifdef LOG
597674Seric 	if (LogLevel > 0)
6010050Seric 		syslog(LOG_ERR, "%s: SYSERR: %s", CurEnv->e_id, &MsgBuf[4]);
61295Seric # endif LOG
62295Seric 	errno = 0;
637762Seric 	if (QuickAbort)
647762Seric 		longjmp(TopFrame, 2);
65295Seric }
66295Seric /*
67295Seric **  USRERR -- Signal user error.
68295Seric **
69295Seric **	This is much like syserr except it is for user errors.
70295Seric **
71295Seric **	Parameters:
72295Seric **		fmt, a, b, c, d -- printf strings
73295Seric **
74295Seric **	Returns:
754084Seric **		none
767762Seric **		Through TopFrame if QuickAbort is set.
77295Seric **
78295Seric **	Side Effects:
791514Seric **		increments Errors.
80295Seric */
81295Seric 
82295Seric /*VARARGS1*/
83295Seric usrerr(fmt, a, b, c, d, e)
84295Seric 	char *fmt;
85295Seric {
86295Seric 	extern char SuprErrs;
874167Seric 	extern char Arpa_Usrerr[];
88*16901Seric 	extern int errno;
89295Seric 
90295Seric 	if (SuprErrs)
914084Seric 		return;
92295Seric 
93*16901Seric 	fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, errno, fmt, a, b, c, d, e);
949389Seric 	puterrmsg(MsgBuf);
958239Seric 
967762Seric 	if (QuickAbort)
977762Seric 		longjmp(TopFrame, 1);
984063Seric }
994063Seric /*
1004063Seric **  MESSAGE -- print message (not necessarily an error)
1014063Seric **
1024063Seric **	Parameters:
1034063Seric **		num -- the default ARPANET error number (in ascii)
1044063Seric **		msg -- the message (printf fmt) -- if it begins
1054063Seric **			with a digit, this number overrides num.
1064063Seric **		a, b, c, d, e -- printf arguments
1074063Seric **
1084063Seric **	Returns:
1094063Seric **		none
1104063Seric **
1114063Seric **	Side Effects:
1124063Seric **		none.
1134063Seric */
1144063Seric 
1154084Seric /*VARARGS2*/
1164063Seric message(num, msg, a, b, c, d, e)
1174063Seric 	register char *num;
1184063Seric 	register char *msg;
1194063Seric {
1204711Seric 	errno = 0;
121*16901Seric 	fmtmsg(MsgBuf, CurEnv->e_to, num, 0, msg, a, b, c, d, e);
1229108Seric 	putmsg(MsgBuf, FALSE);
1237613Seric }
1247613Seric /*
1258239Seric **  NMESSAGE -- print message (not necessarily an error)
1268239Seric **
1278239Seric **	Just like "message" except it never puts the to... tag on.
1288239Seric **
1298239Seric **	Parameters:
1308239Seric **		num -- the default ARPANET error number (in ascii)
1318239Seric **		msg -- the message (printf fmt) -- if it begins
1328239Seric **			with a digit, this number overrides num.
1338239Seric **		a, b, c, d, e -- printf arguments
1348239Seric **
1358239Seric **	Returns:
1368239Seric **		none
1378239Seric **
1388239Seric **	Side Effects:
1398239Seric **		none.
1408239Seric */
1418239Seric 
1428239Seric /*VARARGS2*/
1438239Seric nmessage(num, msg, a, b, c, d, e)
1448239Seric 	register char *num;
1458239Seric 	register char *msg;
1468239Seric {
1478239Seric 	errno = 0;
148*16901Seric 	fmtmsg(MsgBuf, (char *) NULL, num, 0, msg, a, b, c, d, e);
1499108Seric 	putmsg(MsgBuf, FALSE);
1508239Seric }
1518239Seric /*
1527613Seric **  PUTMSG -- output error message to transcript and channel
1537613Seric **
1547613Seric **	Parameters:
1557613Seric **		msg -- message to output (in SMTP format).
1569108Seric **		holdmsg -- if TRUE, don't output a copy of the message to
1579108Seric **			our output channel.
1587613Seric **
1597613Seric **	Returns:
1607613Seric **		none.
1617613Seric **
1627613Seric **	Side Effects:
1637613Seric **		Outputs msg to the transcript.
1647613Seric **		If appropriate, outputs it to the channel.
1657613Seric **		Deletes SMTP reply code number as appropriate.
1667613Seric */
1674711Seric 
1689108Seric putmsg(msg, holdmsg)
1697613Seric 	char *msg;
1709108Seric 	bool holdmsg;
1717613Seric {
17214900Seric 	/* output to transcript if serious */
17314900Seric 	if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5'))
17414900Seric 		fprintf(CurEnv->e_xfp, "%s\n", msg);
1754711Seric 
1764711Seric 	/* output to channel if appropriate */
1779108Seric 	if (!holdmsg && (Verbose || msg[0] != '0'))
1784063Seric 	{
1797275Seric 		(void) fflush(stdout);
1809277Seric 		if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
1817613Seric 			fprintf(OutChannel, "%s\r\n", msg);
1824711Seric 		else
1837613Seric 			fprintf(OutChannel, "%s\n", &msg[4]);
1844711Seric 		(void) fflush(OutChannel);
1854063Seric 	}
1869389Seric }
1879389Seric /*
1889389Seric **  PUTERRMSG -- like putmsg, but does special processing for error messages
1899389Seric **
1909389Seric **	Parameters:
1919389Seric **		msg -- the message to output.
1929389Seric **
1939389Seric **	Returns:
1949389Seric **		none.
1959389Seric **
1969389Seric **	Side Effects:
1979389Seric **		Sets the fatal error bit in the envelope as appropriate.
1989389Seric */
1998239Seric 
2009389Seric puterrmsg(msg)
2019389Seric 	char *msg;
2029389Seric {
2039389Seric 	/* output the message as usual */
2049389Seric 	putmsg(msg, HoldErrs);
2059389Seric 
2069389Seric 	/* signal the error */
2079389Seric 	Errors++;
2089389Seric 	if (msg[0] == '5')
2099336Seric 		CurEnv->e_flags |= EF_FATALERRS;
2104711Seric }
2114711Seric /*
2124711Seric **  FMTMSG -- format a message into buffer.
2134711Seric **
2144711Seric **	Parameters:
2154711Seric **		eb -- error buffer to get result.
2164711Seric **		to -- the recipient tag for this message.
2174711Seric **		num -- arpanet error number.
218*16901Seric **		en -- the error number to display.
2194711Seric **		fmt -- format of string.
2204711Seric **		a, b, c, d, e -- arguments.
2214711Seric **
2224711Seric **	Returns:
2234711Seric **		none.
2244711Seric **
2254711Seric **	Side Effects:
2264711Seric **		none.
2274711Seric */
2284063Seric 
229*16901Seric /*VARARGS5*/
2304711Seric static
231*16901Seric fmtmsg(eb, to, num, eno, fmt, a, b, c, d, e)
2324711Seric 	register char *eb;
2334711Seric 	char *to;
2344711Seric 	char *num;
235*16901Seric 	int en;
2364711Seric 	char *fmt;
2374711Seric {
2384711Seric 	char del;
2394711Seric 
2404711Seric 	/* output the reply code */
2414711Seric 	if (isdigit(*fmt))
2424577Seric 	{
2434711Seric 		num = fmt;
2444711Seric 		fmt += 4;
2454711Seric 	}
2464711Seric 	if (num[3] == '-')
2474711Seric 		del = '-';
2484711Seric 	else
2494711Seric 		del = ' ';
2504711Seric 	(void) sprintf(eb, "%3.3s%c", num, del);
2514711Seric 	eb += 4;
2524063Seric 
2539372Seric 	/* output the file name and line number */
2549372Seric 	if (FileName != NULL)
2559372Seric 	{
2569372Seric 		(void) sprintf(eb, "%s: line %d: ", FileName, LineNumber);
2579372Seric 		eb += strlen(eb);
2589372Seric 	}
2599372Seric 
2604711Seric 	/* output the "to" person */
2614711Seric 	if (to != NULL && to[0] != '\0')
2624711Seric 	{
2634711Seric 		(void) sprintf(eb, "%s... ", to);
2645201Seric 		while (*eb != '\0')
2655201Seric 			*eb++ &= 0177;
2664711Seric 	}
2674711Seric 
2684711Seric 	/* output the message */
2694711Seric 	(void) sprintf(eb, fmt, a, b, c, d, e);
2705201Seric 	while (*eb != '\0')
2715201Seric 		*eb++ &= 0177;
2724711Seric 
2734711Seric 	/* output the error code, if any */
2744711Seric 	if (errno != 0)
2754711Seric 	{
27615136Seric 		extern char *errstring();
27715136Seric 
27815136Seric 		(void) sprintf(eb, ": %s", errstring(errno));
2794711Seric 		eb += strlen(eb);
2804577Seric 	}
281295Seric }
28215136Seric /*
28315136Seric **  ERRSTRING -- return string description of error code
28415136Seric **
28515136Seric **	Parameters:
28615136Seric **		errno -- the error number to translate
28715136Seric **
28815136Seric **	Returns:
28915136Seric **		A string description of errno.
29015136Seric **
29115136Seric **	Side Effects:
29215136Seric **		none.
29315136Seric */
29415136Seric 
29515136Seric char *
29615136Seric errstring(errno)
29715136Seric 	int errno;
29815136Seric {
29915136Seric 	extern char *sys_errlist[];
30015136Seric 	extern int sys_nerr;
30115136Seric 	static char buf[50];
30215136Seric 
30315136Seric 	if (errno > 0 && errno < sys_nerr)
30415136Seric 		return (sys_errlist[errno]);
30515136Seric 
30615136Seric 	(void) sprintf(buf, "Error %d", errno);
30715136Seric 	return (buf);
30815136Seric }
309