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