|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Eric P. Allman
3: * Copyright (c) 1988 Regents of the University of California.
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms are permitted provided
7: * that: (1) source distributions retain this entire copyright notice and
8: * comment, and (2) distributions including binaries display the following
9: * acknowledgement: ``This product includes software developed by the
10: * University of California, Berkeley and its contributors'' in the
11: * documentation or other materials provided with the distribution and in
12: * all advertising materials mentioning features or use of this software.
13: * Neither the name of the University nor the names of its contributors may
14: * be used to endorse or promote products derived from this software without
15: * specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: */
20:
21: #ifndef lint
22: static char sccsid[] = "@(#)err.c 5.10 (Berkeley) 6/1/90";
23: #endif /* not lint */
24:
25: # include "sendmail.h"
26: # include <errno.h>
27: # include <netdb.h>
28:
29: /*
30: ** SYSERR -- Print error message.
31: **
32: ** Prints an error message via printf to the diagnostic
33: ** output. If LOG is defined, it logs it also.
34: **
35: ** Parameters:
36: ** f -- the format string
37: ** a, b, c, d, e -- parameters
38: **
39: ** Returns:
40: ** none
41: ** Through TopFrame if QuickAbort is set.
42: **
43: ** Side Effects:
44: ** increments Errors.
45: ** sets ExitStat.
46: */
47:
48: # ifdef lint
49: int sys_nerr;
50: char *sys_errlist[];
51: # endif lint
52: char MsgBuf[BUFSIZ*2]; /* text of most recent message */
53:
54: /*VARARGS1*/
55: syserr(fmt, a, b, c, d, e)
56: char *fmt;
57: {
58: register char *p;
59: int olderrno = errno;
60: extern char Arpa_PSyserr[];
61: extern char Arpa_TSyserr[];
62:
63: /* format and output the error message */
64: if (olderrno == 0)
65: p = Arpa_PSyserr;
66: else
67: p = Arpa_TSyserr;
68: fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, a, b, c, d, e);
69: puterrmsg(MsgBuf);
70:
71: /* determine exit status if not already set */
72: if (ExitStat == EX_OK)
73: {
74: if (olderrno == 0)
75: ExitStat = EX_SOFTWARE;
76: else
77: ExitStat = EX_OSERR;
78: }
79:
80: # ifdef LOG
81: if (LogLevel > 0)
82: syslog(LOG_CRIT, "%s: SYSERR: %s",
83: CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
84: &MsgBuf[4]);
85: # endif LOG
86: errno = 0;
87: if (QuickAbort)
88: longjmp(TopFrame, 2);
89: }
90: /*
91: ** USRERR -- Signal user error.
92: **
93: ** This is much like syserr except it is for user errors.
94: **
95: ** Parameters:
96: ** fmt, a, b, c, d -- printf strings
97: **
98: ** Returns:
99: ** none
100: ** Through TopFrame if QuickAbort is set.
101: **
102: ** Side Effects:
103: ** increments Errors.
104: */
105:
106: /*VARARGS1*/
107: usrerr(fmt, a, b, c, d, e)
108: char *fmt;
109: {
110: extern char SuprErrs;
111: extern char Arpa_Usrerr[];
112: extern int errno;
113:
114: if (SuprErrs)
115: return;
116:
117: fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, errno, fmt, a, b, c, d, e);
118: puterrmsg(MsgBuf);
119:
120: if (QuickAbort)
121: longjmp(TopFrame, 1);
122: }
123: /*
124: ** MESSAGE -- print message (not necessarily an error)
125: **
126: ** Parameters:
127: ** num -- the default ARPANET error number (in ascii)
128: ** msg -- the message (printf fmt) -- if it begins
129: ** with a digit, this number overrides num.
130: ** a, b, c, d, e -- printf arguments
131: **
132: ** Returns:
133: ** none
134: **
135: ** Side Effects:
136: ** none.
137: */
138:
139: /*VARARGS2*/
140: message(num, msg, a, b, c, d, e)
141: register char *num;
142: register char *msg;
143: {
144: errno = 0;
145: fmtmsg(MsgBuf, CurEnv->e_to, num, 0, msg, a, b, c, d, e);
146: putmsg(MsgBuf, FALSE);
147: }
148: /*
149: ** NMESSAGE -- print message (not necessarily an error)
150: **
151: ** Just like "message" except it never puts the to... tag on.
152: **
153: ** Parameters:
154: ** num -- the default ARPANET error number (in ascii)
155: ** msg -- the message (printf fmt) -- if it begins
156: ** with three digits, this number overrides num.
157: ** a, b, c, d, e -- printf arguments
158: **
159: ** Returns:
160: ** none
161: **
162: ** Side Effects:
163: ** none.
164: */
165:
166: /*VARARGS2*/
167: nmessage(num, msg, a, b, c, d, e)
168: register char *num;
169: register char *msg;
170: {
171: errno = 0;
172: fmtmsg(MsgBuf, (char *) NULL, num, 0, msg, a, b, c, d, e);
173: putmsg(MsgBuf, FALSE);
174: }
175: /*
176: ** PUTMSG -- output error message to transcript and channel
177: **
178: ** Parameters:
179: ** msg -- message to output (in SMTP format).
180: ** holdmsg -- if TRUE, don't output a copy of the message to
181: ** our output channel.
182: **
183: ** Returns:
184: ** none.
185: **
186: ** Side Effects:
187: ** Outputs msg to the transcript.
188: ** If appropriate, outputs it to the channel.
189: ** Deletes SMTP reply code number as appropriate.
190: */
191:
192: putmsg(msg, holdmsg)
193: char *msg;
194: bool holdmsg;
195: {
196: /* output to transcript if serious */
197: if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5'))
198: fprintf(CurEnv->e_xfp, "%s\n", msg);
199:
200: /* output to channel if appropriate */
201: if (!holdmsg && (Verbose || msg[0] != '0'))
202: {
203: (void) fflush(stdout);
204: if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
205: fprintf(OutChannel, "%s\r\n", msg);
206: else
207: fprintf(OutChannel, "%s\n", &msg[4]);
208: (void) fflush(OutChannel);
209: }
210: }
211: /*
212: ** PUTERRMSG -- like putmsg, but does special processing for error messages
213: **
214: ** Parameters:
215: ** msg -- the message to output.
216: **
217: ** Returns:
218: ** none.
219: **
220: ** Side Effects:
221: ** Sets the fatal error bit in the envelope as appropriate.
222: */
223:
224: puterrmsg(msg)
225: char *msg;
226: {
227: /* output the message as usual */
228: putmsg(msg, HoldErrs);
229:
230: /* signal the error */
231: Errors++;
232: if (msg[0] == '5')
233: CurEnv->e_flags |= EF_FATALERRS;
234: }
235: /*
236: ** FMTMSG -- format a message into buffer.
237: **
238: ** Parameters:
239: ** eb -- error buffer to get result.
240: ** to -- the recipient tag for this message.
241: ** num -- arpanet error number.
242: ** en -- the error number to display.
243: ** fmt -- format of string.
244: ** a, b, c, d, e -- arguments.
245: **
246: ** Returns:
247: ** none.
248: **
249: ** Side Effects:
250: ** none.
251: */
252:
253: /*VARARGS5*/
254: static
255: fmtmsg(eb, to, num, eno, fmt, a, b, c, d, e)
256: register char *eb;
257: char *to;
258: char *num;
259: int eno;
260: char *fmt;
261: {
262: char del;
263:
264: /* output the reply code */
265: if (isdigit(fmt[0]) && isdigit(fmt[1]) && isdigit(fmt[2]))
266: {
267: num = fmt;
268: fmt += 4;
269: }
270: if (num[3] == '-')
271: del = '-';
272: else
273: del = ' ';
274: (void) sprintf(eb, "%3.3s%c", num, del);
275: eb += 4;
276:
277: /* output the file name and line number */
278: if (FileName != NULL)
279: {
280: (void) sprintf(eb, "%s: line %d: ", FileName, LineNumber);
281: eb += strlen(eb);
282: }
283:
284: /* output the "to" person */
285: if (to != NULL && to[0] != '\0')
286: {
287: (void) sprintf(eb, "%s... ", to);
288: while (*eb != '\0')
289: *eb++ &= 0177;
290: }
291:
292: /* output the message */
293: (void) sprintf(eb, fmt, a, b, c, d, e);
294: while (*eb != '\0')
295: *eb++ &= 0177;
296:
297: /* output the error code, if any */
298: if (eno != 0)
299: {
300: extern char *errstring();
301:
302: (void) sprintf(eb, ": %s", errstring(eno));
303: eb += strlen(eb);
304: }
305: }
306: /*
307: ** ERRSTRING -- return string description of error code
308: **
309: ** Parameters:
310: ** errno -- the error number to translate
311: **
312: ** Returns:
313: ** A string description of errno.
314: **
315: ** Side Effects:
316: ** none.
317: */
318:
319: char *
320: errstring(errno)
321: int errno;
322: {
323: extern char *sys_errlist[];
324: extern int sys_nerr;
325: static char buf[100];
326: # ifdef SMTP
327: extern char *SmtpPhase;
328: # endif SMTP
329:
330: # ifdef DAEMON
331: # ifdef VMUNIX
332: /*
333: ** Handle special network error codes.
334: **
335: ** These are 4.2/4.3bsd specific; they should be in daemon.c.
336: */
337:
338: switch (errno)
339: {
340: case ETIMEDOUT:
341: case ECONNRESET:
342: (void) strcpy(buf, sys_errlist[errno]);
343: if (SmtpPhase != NULL)
344: {
345: (void) strcat(buf, " during ");
346: (void) strcat(buf, SmtpPhase);
347: }
348: if (CurHostName != NULL)
349: {
350: (void) strcat(buf, " with ");
351: (void) strcat(buf, CurHostName);
352: }
353: return (buf);
354:
355: case EHOSTDOWN:
356: if (CurHostName == NULL)
357: break;
358: (void) sprintf(buf, "Host %s is down", CurHostName);
359: return (buf);
360:
361: case ECONNREFUSED:
362: if (CurHostName == NULL)
363: break;
364: (void) sprintf(buf, "Connection refused by %s", CurHostName);
365: return (buf);
366:
367: case (TRY_AGAIN+MAX_ERRNO):
368: (void) sprintf(buf, "Host Name Lookup Failure");
369: return (buf);
370: }
371: # endif VMUNIX
372: # endif DAEMON
373:
374: if (errno > 0 && errno < sys_nerr)
375: return (sys_errlist[errno]);
376:
377: (void) sprintf(buf, "Error %d", errno);
378: return (buf);
379: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.