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