Commit | Line | Data |
---|---|---|
b2a81223 | 1 | /* |
dc45ba8c | 2 | * Copyright (c) 1983 Eric P. Allman |
eb0bafab KB |
3 | * Copyright (c) 1988, 1993 |
4 | * The Regents of the University of California. All rights reserved. | |
bee79b64 | 5 | * |
417f7a11 | 6 | * %sccs.include.redist.c% |
bee79b64 | 7 | */ |
b2a81223 DF |
8 | |
9 | #ifndef lint | |
5b7a2dfe | 10 | static char sccsid[] = "@(#)err.c 8.32 (Berkeley) %G%"; |
bee79b64 | 11 | #endif /* not lint */ |
b2a81223 | 12 | |
96faada8 | 13 | # include "sendmail.h" |
2e3062fe | 14 | # include <errno.h> |
b3cbe40f EA |
15 | |
16 | /* | |
d916f0ca | 17 | ** SYSERR -- Print error message. |
b3cbe40f EA |
18 | ** |
19 | ** Prints an error message via printf to the diagnostic | |
20 | ** output. If LOG is defined, it logs it also. | |
21 | ** | |
e0539260 EA |
22 | ** If the first character of the syserr message is `!' it will |
23 | ** log this as an ALERT message and exit immediately. This can | |
24 | ** leave queue files in an indeterminate state, so it should not | |
25 | ** be used lightly. | |
26 | ** | |
b3cbe40f | 27 | ** Parameters: |
833ad957 EA |
28 | ** fmt -- the format string. If it does not begin with |
29 | ** a three-digit SMTP reply code, either 554 or | |
30 | ** 451 is assumed depending on whether errno | |
31 | ** is set. | |
32 | ** (others) -- parameters | |
b3cbe40f EA |
33 | ** |
34 | ** Returns: | |
29871fef | 35 | ** none |
633a2e02 | 36 | ** Through TopFrame if QuickAbort is set. |
b3cbe40f EA |
37 | ** |
38 | ** Side Effects: | |
d916f0ca EA |
39 | ** increments Errors. |
40 | ** sets ExitStat. | |
b3cbe40f EA |
41 | */ |
42 | ||
9974ec30 EA |
43 | char MsgBuf[BUFSIZ*2]; /* text of most recent message */ |
44 | char HeldMessageBuf[sizeof MsgBuf]; /* for held messages */ | |
29871fef | 45 | |
35f1f39e EA |
46 | static void fmtmsg(); |
47 | ||
efe7f723 | 48 | #if NAMED_BIND && !defined(NO_DATA) |
35f1f39e EA |
49 | # define NO_DATA NO_ADDRESS |
50 | #endif | |
0df908a9 | 51 | |
36335805 | 52 | void |
b3cbe40f | 53 | /*VARARGS1*/ |
6e99f903 | 54 | #ifdef __STDC__ |
c51d6c4c | 55 | syserr(const char *fmt, ...) |
6e99f903 EA |
56 | #else |
57 | syserr(fmt, va_alist) | |
c51d6c4c | 58 | const char *fmt; |
6e99f903 EA |
59 | va_dcl |
60 | #endif | |
b3cbe40f | 61 | { |
177b9da3 EA |
62 | register char *p; |
63 | int olderrno = errno; | |
e0539260 | 64 | bool panic; |
41be8f1c EA |
65 | #ifdef LOG |
66 | char *uname; | |
67 | struct passwd *pw; | |
68 | char ubuf[80]; | |
69 | #endif | |
5229f34d | 70 | VA_LOCAL_DECL |
b3cbe40f | 71 | |
e0539260 EA |
72 | panic = *fmt == '!'; |
73 | if (panic) | |
74 | fmt++; | |
75 | ||
d5dba2cd | 76 | /* format and output the error message */ |
177b9da3 | 77 | if (olderrno == 0) |
b6edea3d | 78 | p = "554"; |
314d2f52 | 79 | else |
b6edea3d | 80 | p = "451"; |
5229f34d EA |
81 | VA_START(fmt); |
82 | fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, ap); | |
83 | VA_END; | |
80482eb5 | 84 | puterrmsg(MsgBuf); |
f4e91ea7 | 85 | |
833ad957 EA |
86 | /* save this message for mailq printing */ |
87 | if (!panic) | |
88 | { | |
89 | if (CurEnv->e_message != NULL) | |
90 | free(CurEnv->e_message); | |
91 | CurEnv->e_message = newstr(MsgBuf + 4); | |
92 | } | |
93 | ||
b3cbe40f EA |
94 | /* determine exit status if not already set */ |
95 | if (ExitStat == EX_OK) | |
96 | { | |
177b9da3 | 97 | if (olderrno == 0) |
b3cbe40f EA |
98 | ExitStat = EX_SOFTWARE; |
99 | else | |
21ec078e | 100 | ExitStat = EX_OSERR; |
ed3d2b02 EA |
101 | if (tTd(54, 1)) |
102 | printf("syserr: ExitStat = %d\n", ExitStat); | |
b3cbe40f EA |
103 | } |
104 | ||
105 | # ifdef LOG | |
5b7a2dfe | 106 | pw = sm_getpwuid(getuid()); |
41be8f1c EA |
107 | if (pw != NULL) |
108 | uname = pw->pw_name; | |
109 | else | |
110 | { | |
111 | uname = ubuf; | |
112 | sprintf(ubuf, "UID%d", getuid()); | |
113 | } | |
114 | ||
9678c96d | 115 | if (LogLevel > 0) |
41be8f1c | 116 | syslog(panic ? LOG_ALERT : LOG_CRIT, "%s: SYSERR(%s): %s", |
3312f93c | 117 | CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id, |
41be8f1c | 118 | uname, &MsgBuf[4]); |
f3d8f6d6 | 119 | # endif /* LOG */ |
35f14050 | 120 | if (olderrno == EMFILE) |
deff97fd | 121 | { |
35f14050 | 122 | printopenfds(TRUE); |
deff97fd EA |
123 | mci_dump_all(TRUE); |
124 | } | |
e0539260 | 125 | if (panic) |
b4f81c5d EA |
126 | { |
127 | #ifdef XLA | |
128 | xla_all_end(); | |
129 | #endif | |
e0539260 | 130 | exit(EX_OSERR); |
b4f81c5d | 131 | } |
b3cbe40f | 132 | errno = 0; |
633a2e02 EA |
133 | if (QuickAbort) |
134 | longjmp(TopFrame, 2); | |
b3cbe40f EA |
135 | } |
136 | \f/* | |
137 | ** USRERR -- Signal user error. | |
138 | ** | |
139 | ** This is much like syserr except it is for user errors. | |
140 | ** | |
141 | ** Parameters: | |
833ad957 EA |
142 | ** fmt -- the format string. If it does not begin with |
143 | ** a three-digit SMTP reply code, 501 is assumed. | |
144 | ** (others) -- printf strings | |
b3cbe40f EA |
145 | ** |
146 | ** Returns: | |
29871fef | 147 | ** none |
633a2e02 | 148 | ** Through TopFrame if QuickAbort is set. |
b3cbe40f EA |
149 | ** |
150 | ** Side Effects: | |
d916f0ca | 151 | ** increments Errors. |
b3cbe40f EA |
152 | */ |
153 | ||
154 | /*VARARGS1*/ | |
94bc039a | 155 | void |
36335805 | 156 | #ifdef __STDC__ |
c51d6c4c | 157 | usrerr(const char *fmt, ...) |
6e99f903 EA |
158 | #else |
159 | usrerr(fmt, va_alist) | |
c51d6c4c | 160 | const char *fmt; |
6e99f903 EA |
161 | va_dcl |
162 | #endif | |
b3cbe40f | 163 | { |
5229f34d | 164 | VA_LOCAL_DECL |
b3cbe40f EA |
165 | |
166 | if (SuprErrs) | |
29871fef | 167 | return; |
f4e91ea7 | 168 | |
5229f34d | 169 | VA_START(fmt); |
75593899 | 170 | fmtmsg(MsgBuf, CurEnv->e_to, "501", 0, fmt, ap); |
5229f34d | 171 | VA_END; |
80482eb5 | 172 | puterrmsg(MsgBuf); |
21f25858 | 173 | |
833ad957 EA |
174 | /* save this message for mailq printing */ |
175 | if (MsgBuf[0] == '5' || (CurEnv->e_message == NULL && MsgBuf[0] == '4')) | |
176 | { | |
177 | if (CurEnv->e_message != NULL) | |
178 | free(CurEnv->e_message); | |
179 | CurEnv->e_message = newstr(MsgBuf + 4); | |
180 | } | |
181 | ||
f61c3c40 | 182 | # ifdef LOG |
68f7099c | 183 | if (LogLevel > 3 && LogUsrErrs) |
f61c3c40 EA |
184 | syslog(LOG_NOTICE, "%s: %s", |
185 | CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id, | |
186 | &MsgBuf[4]); | |
f3d8f6d6 | 187 | # endif /* LOG */ |
f61c3c40 | 188 | |
633a2e02 EA |
189 | if (QuickAbort) |
190 | longjmp(TopFrame, 1); | |
f4e91ea7 EA |
191 | } |
192 | \f/* | |
193 | ** MESSAGE -- print message (not necessarily an error) | |
194 | ** | |
195 | ** Parameters: | |
62869b50 EA |
196 | ** msg -- the message (printf fmt) -- it can begin with |
197 | ** an SMTP reply code. If not, 050 is assumed. | |
833ad957 | 198 | ** (others) -- printf arguments |
f4e91ea7 EA |
199 | ** |
200 | ** Returns: | |
201 | ** none | |
202 | ** | |
203 | ** Side Effects: | |
204 | ** none. | |
205 | */ | |
206 | ||
29871fef | 207 | /*VARARGS2*/ |
94bc039a | 208 | void |
319b1ec0 | 209 | #ifdef __STDC__ |
c51d6c4c | 210 | message(const char *msg, ...) |
6e99f903 | 211 | #else |
b6edea3d | 212 | message(msg, va_alist) |
c51d6c4c | 213 | const char *msg; |
6e99f903 EA |
214 | va_dcl |
215 | #endif | |
f4e91ea7 | 216 | { |
5229f34d EA |
217 | VA_LOCAL_DECL |
218 | ||
49086753 | 219 | errno = 0; |
5229f34d | 220 | VA_START(msg); |
b6edea3d | 221 | fmtmsg(MsgBuf, CurEnv->e_to, "050", 0, msg, ap); |
5229f34d | 222 | VA_END; |
9974ec30 | 223 | putoutmsg(MsgBuf, FALSE, FALSE); |
833ad957 EA |
224 | |
225 | /* save this message for mailq printing */ | |
226 | if (MsgBuf[0] == '5' || (CurEnv->e_message == NULL && MsgBuf[0] == '4')) | |
227 | { | |
228 | if (CurEnv->e_message != NULL) | |
229 | free(CurEnv->e_message); | |
230 | CurEnv->e_message = newstr(MsgBuf + 4); | |
231 | } | |
015bb651 EA |
232 | } |
233 | \f/* | |
21f25858 EA |
234 | ** NMESSAGE -- print message (not necessarily an error) |
235 | ** | |
236 | ** Just like "message" except it never puts the to... tag on. | |
237 | ** | |
238 | ** Parameters: | |
21f25858 | 239 | ** msg -- the message (printf fmt) -- if it begins |
833ad957 EA |
240 | ** with a three digit SMTP reply code, that is used, |
241 | ** otherwise 050 is assumed. | |
242 | ** (others) -- printf arguments | |
21f25858 EA |
243 | ** |
244 | ** Returns: | |
245 | ** none | |
246 | ** | |
247 | ** Side Effects: | |
248 | ** none. | |
249 | */ | |
250 | ||
251 | /*VARARGS2*/ | |
94bc039a | 252 | void |
319b1ec0 | 253 | #ifdef __STDC__ |
c51d6c4c | 254 | nmessage(const char *msg, ...) |
6e99f903 | 255 | #else |
b6edea3d | 256 | nmessage(msg, va_alist) |
c51d6c4c | 257 | const char *msg; |
6e99f903 EA |
258 | va_dcl |
259 | #endif | |
21f25858 | 260 | { |
5229f34d EA |
261 | VA_LOCAL_DECL |
262 | ||
21f25858 | 263 | errno = 0; |
5229f34d | 264 | VA_START(msg); |
b6edea3d | 265 | fmtmsg(MsgBuf, (char *) NULL, "050", 0, msg, ap); |
5229f34d | 266 | VA_END; |
9974ec30 | 267 | putoutmsg(MsgBuf, FALSE, FALSE); |
21f25858 EA |
268 | } |
269 | \f/* | |
8e5c6745 | 270 | ** PUTOUTMSG -- output error message to transcript and channel |
015bb651 EA |
271 | ** |
272 | ** Parameters: | |
273 | ** msg -- message to output (in SMTP format). | |
6a766659 EA |
274 | ** holdmsg -- if TRUE, don't output a copy of the message to |
275 | ** our output channel. | |
9974ec30 EA |
276 | ** heldmsg -- if TRUE, this is a previously held message; |
277 | ** don't log it to the transcript file. | |
015bb651 EA |
278 | ** |
279 | ** Returns: | |
280 | ** none. | |
281 | ** | |
282 | ** Side Effects: | |
283 | ** Outputs msg to the transcript. | |
284 | ** If appropriate, outputs it to the channel. | |
285 | ** Deletes SMTP reply code number as appropriate. | |
286 | */ | |
49086753 | 287 | |
9974ec30 | 288 | putoutmsg(msg, holdmsg, heldmsg) |
015bb651 | 289 | char *msg; |
6a766659 | 290 | bool holdmsg; |
9974ec30 | 291 | bool heldmsg; |
015bb651 | 292 | { |
9acae8cd EA |
293 | /* display for debugging */ |
294 | if (tTd(54, 8)) | |
9974ec30 EA |
295 | printf("--- %s%s%s\n", msg, holdmsg ? " (hold)" : "", |
296 | heldmsg ? " (held)" : ""); | |
9acae8cd | 297 | |
d7dbe85b | 298 | /* output to transcript if serious */ |
9974ec30 | 299 | if (!heldmsg && CurEnv->e_xfp != NULL && strchr("456", msg[0]) != NULL) |
d7dbe85b | 300 | fprintf(CurEnv->e_xfp, "%s\n", msg); |
49086753 EA |
301 | |
302 | /* output to channel if appropriate */ | |
9974ec30 | 303 | if (!Verbose && msg[0] == '0') |
d907841d | 304 | return; |
9974ec30 EA |
305 | if (holdmsg) |
306 | { | |
307 | /* save for possible future display */ | |
308 | strcpy(HeldMessageBuf, msg); | |
309 | return; | |
310 | } | |
d907841d | 311 | |
5e2168d0 EA |
312 | /* map warnings to something SMTP can handle */ |
313 | if (msg[0] == '6') | |
314 | msg[0] = '5'; | |
315 | ||
d907841d | 316 | (void) fflush(stdout); |
33cbaada EA |
317 | |
318 | /* if DisConnected, OutChannel now points to the transcript */ | |
319 | if (!DisConnected && | |
320 | (OpMode == MD_SMTP || OpMode == MD_DAEMON || OpMode == MD_ARPAFTP)) | |
d907841d EA |
321 | fprintf(OutChannel, "%s\r\n", msg); |
322 | else | |
323 | fprintf(OutChannel, "%s\n", &msg[4]); | |
8e5c6745 EA |
324 | if (TrafficLogFile != NULL) |
325 | fprintf(TrafficLogFile, "%05d >>> %s\n", getpid(), | |
198d9e9c | 326 | (OpMode == MD_SMTP || OpMode == MD_DAEMON) ? msg : &msg[4]); |
d907841d EA |
327 | if (msg[3] == ' ') |
328 | (void) fflush(OutChannel); | |
33cbaada | 329 | if (!ferror(OutChannel) || DisConnected) |
d907841d EA |
330 | return; |
331 | ||
b3454503 EA |
332 | /* |
333 | ** Error on output -- if reporting lost channel, just ignore it. | |
334 | ** Also, ignore errors from QUIT response (221 message) -- some | |
335 | ** rude servers don't read result. | |
336 | */ | |
337 | ||
338 | if (feof(InChannel) || ferror(InChannel) || strncmp(msg, "221", 3) == 0) | |
d907841d EA |
339 | return; |
340 | ||
341 | /* can't call syserr, 'cause we are using MsgBuf */ | |
342 | HoldErrs = TRUE; | |
a9145676 | 343 | #ifdef LOG |
d907841d EA |
344 | if (LogLevel > 0) |
345 | syslog(LOG_CRIT, | |
67d76dc4 | 346 | "%s: SYSERR: putoutmsg (%s): error on output channel sending \"%s\": %s", |
d907841d | 347 | CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id, |
548e1aec | 348 | CurHostName == NULL ? "NO-HOST" : CurHostName, |
67d76dc4 | 349 | msg, errstring(errno)); |
a9145676 | 350 | #endif |
80482eb5 EA |
351 | } |
352 | \f/* | |
8e5c6745 | 353 | ** PUTERRMSG -- like putoutmsg, but does special processing for error messages |
80482eb5 EA |
354 | ** |
355 | ** Parameters: | |
356 | ** msg -- the message to output. | |
357 | ** | |
358 | ** Returns: | |
359 | ** none. | |
360 | ** | |
361 | ** Side Effects: | |
362 | ** Sets the fatal error bit in the envelope as appropriate. | |
363 | */ | |
21f25858 | 364 | |
80482eb5 EA |
365 | puterrmsg(msg) |
366 | char *msg; | |
367 | { | |
5e2168d0 EA |
368 | char msgcode = msg[0]; |
369 | ||
80482eb5 | 370 | /* output the message as usual */ |
9974ec30 | 371 | putoutmsg(msg, HoldErrs, FALSE); |
21f25858 | 372 | |
80482eb5 | 373 | /* signal the error */ |
e67e6cf6 | 374 | Errors++; |
2aad48ef EA |
375 | if (msgcode == '6') |
376 | { | |
377 | /* notify the postmaster */ | |
378 | CurEnv->e_flags |= EF_PM_NOTIFY; | |
379 | } | |
b5c513a7 EA |
380 | else if ((msgcode == '4' || msgcode == '5') && |
381 | bitset(EF_GLOBALERRS, CurEnv->e_flags)) | |
e67e6cf6 EA |
382 | { |
383 | /* mark long-term fatal errors */ | |
384 | CurEnv->e_flags |= EF_FATALERRS; | |
385 | } | |
49086753 EA |
386 | } |
387 | \f/* | |
388 | ** FMTMSG -- format a message into buffer. | |
389 | ** | |
390 | ** Parameters: | |
391 | ** eb -- error buffer to get result. | |
392 | ** to -- the recipient tag for this message. | |
393 | ** num -- arpanet error number. | |
177b9da3 | 394 | ** en -- the error number to display. |
49086753 EA |
395 | ** fmt -- format of string. |
396 | ** a, b, c, d, e -- arguments. | |
397 | ** | |
398 | ** Returns: | |
399 | ** none. | |
400 | ** | |
401 | ** Side Effects: | |
402 | ** none. | |
403 | */ | |
404 | ||
0df908a9 | 405 | static void |
5229f34d | 406 | fmtmsg(eb, to, num, eno, fmt, ap) |
49086753 EA |
407 | register char *eb; |
408 | char *to; | |
409 | char *num; | |
e1e01376 | 410 | int eno; |
49086753 | 411 | char *fmt; |
5229f34d | 412 | va_list ap; |
49086753 EA |
413 | { |
414 | char del; | |
c281eee3 | 415 | char *meb; |
49086753 EA |
416 | |
417 | /* output the reply code */ | |
2e3062fe | 418 | if (isdigit(fmt[0]) && isdigit(fmt[1]) && isdigit(fmt[2])) |
f4e91ea7 | 419 | { |
49086753 EA |
420 | num = fmt; |
421 | fmt += 4; | |
f4e91ea7 | 422 | } |
49086753 EA |
423 | if (num[3] == '-') |
424 | del = '-'; | |
425 | else | |
426 | del = ' '; | |
427 | (void) sprintf(eb, "%3.3s%c", num, del); | |
428 | eb += 4; | |
f4e91ea7 | 429 | |
7338e3d4 EA |
430 | /* output the file name and line number */ |
431 | if (FileName != NULL) | |
432 | { | |
433 | (void) sprintf(eb, "%s: line %d: ", FileName, LineNumber); | |
434 | eb += strlen(eb); | |
435 | } | |
436 | ||
49086753 EA |
437 | /* output the "to" person */ |
438 | if (to != NULL && to[0] != '\0') | |
34d37b7d | 439 | { |
bab2ae18 | 440 | (void) sprintf(eb, "%s... ", shortenstring(to, 203)); |
6593367a EA |
441 | while (*eb != '\0') |
442 | *eb++ &= 0177; | |
49086753 EA |
443 | } |
444 | ||
c281eee3 EA |
445 | meb = eb; |
446 | ||
49086753 | 447 | /* output the message */ |
5229f34d | 448 | (void) vsprintf(eb, fmt, ap); |
6593367a EA |
449 | while (*eb != '\0') |
450 | *eb++ &= 0177; | |
34d37b7d | 451 | |
49086753 | 452 | /* output the error code, if any */ |
e1e01376 | 453 | if (eno != 0) |
49086753 | 454 | { |
e1e01376 | 455 | (void) sprintf(eb, ": %s", errstring(eno)); |
49086753 | 456 | eb += strlen(eb); |
34d37b7d | 457 | } |
b3cbe40f | 458 | } |
e41c463e | 459 | \f/* |
9974ec30 EA |
460 | ** BUFFER_ERRORS -- arrange to buffer future error messages |
461 | ** | |
462 | ** Parameters: | |
463 | ** none | |
464 | ** | |
465 | ** Returns: | |
466 | ** none. | |
467 | */ | |
468 | ||
469 | void | |
470 | buffer_errors() | |
471 | { | |
472 | HeldMessageBuf[0] = '\0'; | |
473 | HoldErrs = TRUE; | |
474 | } | |
475 | \f/* | |
476 | ** FLUSH_ERRORS -- flush the held error message buffer | |
477 | ** | |
478 | ** Parameters: | |
479 | ** print -- if set, print the message, otherwise just | |
480 | ** delete it. | |
481 | ** | |
482 | ** Returns: | |
483 | ** none. | |
484 | */ | |
485 | ||
486 | void | |
487 | flush_errors(print) | |
488 | bool print; | |
489 | { | |
490 | if (print && HeldMessageBuf[0] != '\0') | |
491 | putoutmsg(HeldMessageBuf, FALSE, TRUE); | |
492 | HeldMessageBuf[0] = '\0'; | |
493 | HoldErrs = FALSE; | |
494 | } | |
495 | \f/* | |
e41c463e EA |
496 | ** ERRSTRING -- return string description of error code |
497 | ** | |
498 | ** Parameters: | |
c583011b | 499 | ** errnum -- the error number to translate |
e41c463e EA |
500 | ** |
501 | ** Returns: | |
c583011b | 502 | ** A string description of errnum. |
e41c463e EA |
503 | ** |
504 | ** Side Effects: | |
505 | ** none. | |
506 | */ | |
507 | ||
713c523f | 508 | const char * |
c583011b EA |
509 | errstring(errnum) |
510 | int errnum; | |
e41c463e | 511 | { |
7b3d4602 | 512 | char *dnsmsg; |
f43b04ce | 513 | static char buf[MAXLINE]; |
d4f6a25e EA |
514 | # ifndef ERRLIST_PREDEFINED |
515 | extern char *sys_errlist[]; | |
516 | extern int sys_nerr; | |
517 | # endif | |
2e3062fe EA |
518 | # ifdef SMTP |
519 | extern char *SmtpPhase; | |
f3d8f6d6 | 520 | # endif /* SMTP */ |
2e3062fe | 521 | |
2e3062fe EA |
522 | /* |
523 | ** Handle special network error codes. | |
524 | ** | |
525 | ** These are 4.2/4.3bsd specific; they should be in daemon.c. | |
526 | */ | |
527 | ||
7b3d4602 | 528 | dnsmsg = NULL; |
c583011b | 529 | switch (errnum) |
2e3062fe | 530 | { |
7763037f | 531 | # if defined(DAEMON) && defined(ETIMEDOUT) |
2e3062fe EA |
532 | case ETIMEDOUT: |
533 | case ECONNRESET: | |
c583011b | 534 | (void) strcpy(buf, sys_errlist[errnum]); |
2e3062fe EA |
535 | if (SmtpPhase != NULL) |
536 | { | |
537 | (void) strcat(buf, " during "); | |
538 | (void) strcat(buf, SmtpPhase); | |
539 | } | |
57c97d4a | 540 | if (CurHostName != NULL) |
2e3062fe EA |
541 | { |
542 | (void) strcat(buf, " with "); | |
57c97d4a | 543 | (void) strcat(buf, CurHostName); |
2e3062fe EA |
544 | } |
545 | return (buf); | |
546 | ||
547 | case EHOSTDOWN: | |
57c97d4a | 548 | if (CurHostName == NULL) |
2e3062fe | 549 | break; |
57c97d4a | 550 | (void) sprintf(buf, "Host %s is down", CurHostName); |
2e3062fe EA |
551 | return (buf); |
552 | ||
553 | case ECONNREFUSED: | |
57c97d4a | 554 | if (CurHostName == NULL) |
2e3062fe | 555 | break; |
57c97d4a | 556 | (void) sprintf(buf, "Connection refused by %s", CurHostName); |
2e3062fe | 557 | return (buf); |
7763037f | 558 | # endif |
9fd1518e | 559 | |
92f2b65e EA |
560 | case EOPENTIMEOUT: |
561 | return "Timeout on file open"; | |
562 | ||
efe7f723 | 563 | # if NAMED_BIND |
92f2b65e | 564 | case HOST_NOT_FOUND + E_DNSBASE: |
7b3d4602 EA |
565 | dnsmsg = "host not found"; |
566 | break; | |
49a282c6 | 567 | |
92f2b65e | 568 | case TRY_AGAIN + E_DNSBASE: |
7b3d4602 EA |
569 | dnsmsg = "host name lookup failure"; |
570 | break; | |
49a282c6 | 571 | |
92f2b65e | 572 | case NO_RECOVERY + E_DNSBASE: |
7b3d4602 EA |
573 | dnsmsg = "non-recoverable error"; |
574 | break; | |
49a282c6 | 575 | |
92f2b65e | 576 | case NO_DATA + E_DNSBASE: |
7b3d4602 EA |
577 | dnsmsg = "no data known"; |
578 | break; | |
6feb509e | 579 | # endif |
7763037f EA |
580 | |
581 | case EPERM: | |
582 | /* SunOS gives "Not owner" -- this is the POSIX message */ | |
583 | return "Operation not permitted"; | |
2e3062fe | 584 | } |
e41c463e | 585 | |
7b3d4602 EA |
586 | if (dnsmsg != NULL) |
587 | { | |
588 | (void) strcpy(buf, "Name server: "); | |
589 | if (CurHostName != NULL) | |
590 | { | |
591 | (void) strcat(buf, CurHostName); | |
592 | (void) strcat(buf, ": "); | |
593 | } | |
594 | (void) strcat(buf, dnsmsg); | |
595 | return buf; | |
596 | } | |
597 | ||
c583011b EA |
598 | if (errnum > 0 && errnum < sys_nerr) |
599 | return (sys_errlist[errnum]); | |
e41c463e | 600 | |
c583011b | 601 | (void) sprintf(buf, "Error %d", errnum); |
e41c463e EA |
602 | return (buf); |
603 | } |