|
|
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.