xref: /original-bsd/usr.sbin/sendmail/src/err.c (revision 39c8fdd5)
1 # include "sendmail.h"
2 
3 SCCSID(@(#)err.c	4.3		10/01/83);
4 
5 /*
6 **  SYSERR -- Print error message.
7 **
8 **	Prints an error message via printf to the diagnostic
9 **	output.  If LOG is defined, it logs it also.
10 **
11 **	Parameters:
12 **		f -- the format string
13 **		a, b, c, d, e -- parameters
14 **
15 **	Returns:
16 **		none
17 **		Through TopFrame if QuickAbort is set.
18 **
19 **	Side Effects:
20 **		increments Errors.
21 **		sets ExitStat.
22 */
23 
24 # ifdef lint
25 int	sys_nerr;
26 char	*sys_errlist[];
27 # endif lint
28 char	MsgBuf[BUFSIZ*2];	/* text of most recent message */
29 
30 /*VARARGS1*/
31 syserr(fmt, a, b, c, d, e)
32 	char *fmt;
33 {
34 	extern char Arpa_PSyserr[];
35 	extern char Arpa_TSyserr[];
36 	register char *p;
37 
38 	/* format and output the error message */
39 	if (errno == 0)
40 		p = Arpa_PSyserr;
41 	else
42 		p = Arpa_TSyserr;
43 	fmtmsg(MsgBuf, (char *) NULL, p, fmt, a, b, c, d, e);
44 	puterrmsg(MsgBuf);
45 
46 	/* determine exit status if not already set */
47 	if (ExitStat == EX_OK)
48 	{
49 		if (errno == 0)
50 			ExitStat = EX_SOFTWARE;
51 		else
52 			ExitStat = EX_OSERR;
53 	}
54 
55 	/* insure that we have a queue id for logging */
56 	(void) queuename(CurEnv, '\0');
57 # ifdef LOG
58 	if (LogLevel > 0)
59 		syslog(LOG_ERR, "%s: SYSERR: %s", CurEnv->e_id, &MsgBuf[4]);
60 # endif LOG
61 	errno = 0;
62 	if (QuickAbort)
63 		longjmp(TopFrame, 2);
64 }
65 /*
66 **  USRERR -- Signal user error.
67 **
68 **	This is much like syserr except it is for user errors.
69 **
70 **	Parameters:
71 **		fmt, a, b, c, d -- printf strings
72 **
73 **	Returns:
74 **		none
75 **		Through TopFrame if QuickAbort is set.
76 **
77 **	Side Effects:
78 **		increments Errors.
79 */
80 
81 /*VARARGS1*/
82 usrerr(fmt, a, b, c, d, e)
83 	char *fmt;
84 {
85 	extern char SuprErrs;
86 	extern char Arpa_Usrerr[];
87 
88 	if (SuprErrs)
89 		return;
90 
91 	fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, fmt, a, b, c, d, e);
92 	puterrmsg(MsgBuf);
93 
94 	if (QuickAbort)
95 		longjmp(TopFrame, 1);
96 }
97 /*
98 **  MESSAGE -- print message (not necessarily an error)
99 **
100 **	Parameters:
101 **		num -- the default ARPANET error number (in ascii)
102 **		msg -- the message (printf fmt) -- if it begins
103 **			with a digit, this number overrides num.
104 **		a, b, c, d, e -- printf arguments
105 **
106 **	Returns:
107 **		none
108 **
109 **	Side Effects:
110 **		none.
111 */
112 
113 /*VARARGS2*/
114 message(num, msg, a, b, c, d, e)
115 	register char *num;
116 	register char *msg;
117 {
118 	errno = 0;
119 	fmtmsg(MsgBuf, CurEnv->e_to, num, msg, a, b, c, d, e);
120 	putmsg(MsgBuf, FALSE);
121 }
122 /*
123 **  NMESSAGE -- print message (not necessarily an error)
124 **
125 **	Just like "message" except it never puts the to... tag on.
126 **
127 **	Parameters:
128 **		num -- the default ARPANET error number (in ascii)
129 **		msg -- the message (printf fmt) -- if it begins
130 **			with a digit, this number overrides num.
131 **		a, b, c, d, e -- printf arguments
132 **
133 **	Returns:
134 **		none
135 **
136 **	Side Effects:
137 **		none.
138 */
139 
140 /*VARARGS2*/
141 nmessage(num, msg, a, b, c, d, e)
142 	register char *num;
143 	register char *msg;
144 {
145 	errno = 0;
146 	fmtmsg(MsgBuf, (char *) NULL, num, msg, a, b, c, d, e);
147 	putmsg(MsgBuf, FALSE);
148 }
149 /*
150 **  PUTMSG -- output error message to transcript and channel
151 **
152 **	Parameters:
153 **		msg -- message to output (in SMTP format).
154 **		holdmsg -- if TRUE, don't output a copy of the message to
155 **			our output channel.
156 **
157 **	Returns:
158 **		none.
159 **
160 **	Side Effects:
161 **		Outputs msg to the transcript.
162 **		If appropriate, outputs it to the channel.
163 **		Deletes SMTP reply code number as appropriate.
164 */
165 
166 putmsg(msg, holdmsg)
167 	char *msg;
168 	bool holdmsg;
169 {
170 	/* output to transcript if serious */
171 	if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5'))
172 		fprintf(CurEnv->e_xfp, "%s\n", msg);
173 
174 	/* output to channel if appropriate */
175 	if (!holdmsg && (Verbose || msg[0] != '0'))
176 	{
177 		(void) fflush(stdout);
178 		if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
179 			fprintf(OutChannel, "%s\r\n", msg);
180 		else
181 			fprintf(OutChannel, "%s\n", &msg[4]);
182 		(void) fflush(OutChannel);
183 	}
184 }
185 /*
186 **  PUTERRMSG -- like putmsg, but does special processing for error messages
187 **
188 **	Parameters:
189 **		msg -- the message to output.
190 **
191 **	Returns:
192 **		none.
193 **
194 **	Side Effects:
195 **		Sets the fatal error bit in the envelope as appropriate.
196 */
197 
198 puterrmsg(msg)
199 	char *msg;
200 {
201 	/* output the message as usual */
202 	putmsg(msg, HoldErrs);
203 
204 	/* signal the error */
205 	Errors++;
206 	if (msg[0] == '5')
207 		CurEnv->e_flags |= EF_FATALERRS;
208 }
209 /*
210 **  FMTMSG -- format a message into buffer.
211 **
212 **	Parameters:
213 **		eb -- error buffer to get result.
214 **		to -- the recipient tag for this message.
215 **		num -- arpanet error number.
216 **		fmt -- format of string.
217 **		a, b, c, d, e -- arguments.
218 **
219 **	Returns:
220 **		none.
221 **
222 **	Side Effects:
223 **		none.
224 */
225 
226 /*VARARGS4*/
227 static
228 fmtmsg(eb, to, num, fmt, a, b, c, d, e)
229 	register char *eb;
230 	char *to;
231 	char *num;
232 	char *fmt;
233 {
234 	char del;
235 
236 	/* output the reply code */
237 	if (isdigit(*fmt))
238 	{
239 		num = fmt;
240 		fmt += 4;
241 	}
242 	if (num[3] == '-')
243 		del = '-';
244 	else
245 		del = ' ';
246 	(void) sprintf(eb, "%3.3s%c", num, del);
247 	eb += 4;
248 
249 	/* output the file name and line number */
250 	if (FileName != NULL)
251 	{
252 		(void) sprintf(eb, "%s: line %d: ", FileName, LineNumber);
253 		eb += strlen(eb);
254 	}
255 
256 	/* output the "to" person */
257 	if (to != NULL && to[0] != '\0')
258 	{
259 		(void) sprintf(eb, "%s... ", to);
260 		while (*eb != '\0')
261 			*eb++ &= 0177;
262 	}
263 
264 	/* output the message */
265 	(void) sprintf(eb, fmt, a, b, c, d, e);
266 	while (*eb != '\0')
267 		*eb++ &= 0177;
268 
269 	/* output the error code, if any */
270 	if (errno != 0)
271 	{
272 		extern char *errstring();
273 
274 		(void) sprintf(eb, ": %s", errstring(errno));
275 		eb += strlen(eb);
276 	}
277 }
278 /*
279 **  ERRSTRING -- return string description of error code
280 **
281 **	Parameters:
282 **		errno -- the error number to translate
283 **
284 **	Returns:
285 **		A string description of errno.
286 **
287 **	Side Effects:
288 **		none.
289 */
290 
291 char *
292 errstring(errno)
293 	int errno;
294 {
295 	extern char *sys_errlist[];
296 	extern int sys_nerr;
297 	static char buf[50];
298 
299 	if (errno > 0 && errno < sys_nerr)
300 		return (sys_errlist[errno]);
301 
302 	(void) sprintf(buf, "Error %d", errno);
303 	return (buf);
304 }
305