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