xref: /csrg-svn/usr.sbin/sendmail/src/err.c (revision 9372)
1 # include "sendmail.h"
2 
3 SCCSID(@(#)err.c	3.36		11/28/82);
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 static 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 	putmsg(MsgBuf, HoldErrs);
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: %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 	putmsg(MsgBuf, HoldErrs);
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 */
171 	if (Xscript != NULL)
172 		fprintf(Xscript, "%s\n", OpMode == MD_SMTP ? msg : &msg[4]);
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 	/* determine error status */
186 	switch (msg[0])
187 	{
188 	  case '5':
189 		CurEnv->e_flags |= EF_FATALERRS;
190 		/* fall through.... */
191 
192 	  case '4':
193 		Errors++;
194 		break;
195 	}
196 }
197 /*
198 **  FMTMSG -- format a message into buffer.
199 **
200 **	Parameters:
201 **		eb -- error buffer to get result.
202 **		to -- the recipient tag for this message.
203 **		num -- arpanet error number.
204 **		fmt -- format of string.
205 **		a, b, c, d, e -- arguments.
206 **
207 **	Returns:
208 **		none.
209 **
210 **	Side Effects:
211 **		none.
212 */
213 
214 /*VARARGS4*/
215 static
216 fmtmsg(eb, to, num, fmt, a, b, c, d, e)
217 	register char *eb;
218 	char *to;
219 	char *num;
220 	char *fmt;
221 {
222 	char del;
223 
224 	/* output the reply code */
225 	if (isdigit(*fmt))
226 	{
227 		num = fmt;
228 		fmt += 4;
229 	}
230 	if (num[3] == '-')
231 		del = '-';
232 	else
233 		del = ' ';
234 	(void) sprintf(eb, "%3.3s%c", num, del);
235 	eb += 4;
236 
237 	/* output the file name and line number */
238 	if (FileName != NULL)
239 	{
240 		(void) sprintf(eb, "%s: line %d: ", FileName, LineNumber);
241 		eb += strlen(eb);
242 	}
243 
244 	/* output the "to" person */
245 	if (to != NULL && to[0] != '\0')
246 	{
247 		(void) sprintf(eb, "%s... ", to);
248 		while (*eb != '\0')
249 			*eb++ &= 0177;
250 	}
251 
252 	/* output the message */
253 	(void) sprintf(eb, fmt, a, b, c, d, e);
254 	while (*eb != '\0')
255 		*eb++ &= 0177;
256 
257 	/* output the error code, if any */
258 	if (errno != 0)
259 	{
260 		extern int sys_nerr;
261 		extern char *sys_errlist[];
262 		if (errno < sys_nerr && errno > 0)
263 			(void) sprintf(eb, ": %s", sys_errlist[errno]);
264 		else
265 			(void) sprintf(eb, ": error %d", errno);
266 		eb += strlen(eb);
267 	}
268 }
269