1: # include "sendmail.h" 2: 3: SCCSID(@(#)err.c 4.1 7/25/83); 4: 5: /* 6: ** SYSERR -- Print error message. 7: ** 8: ** Prints an error message via printf to the diagnostic 9: ** output. If LOG is defined, it logs it also. 10: ** 11: ** Parameters: 12: ** f -- the format string 13: ** a, b, c, d, e -- parameters 14: ** 15: ** Returns: 16: ** none 17: ** Through TopFrame if QuickAbort is set. 18: ** 19: ** Side Effects: 20: ** increments Errors. 21: ** sets ExitStat. 22: */ 23: 24: # ifdef lint 25: int sys_nerr; 26: char *sys_errlist[]; 27: # endif lint 28: char MsgBuf[BUFSIZ*2]; /* text of most recent message */ 29: 30: /*VARARGS1*/ 31: syserr(fmt, a, b, c, d, e) 32: char *fmt; 33: { 34: extern char Arpa_PSyserr[]; 35: extern char Arpa_TSyserr[]; 36: register char *p; 37: 38: /* format and output the error message */ 39: if (errno == 0) 40: p = Arpa_PSyserr; 41: else 42: p = Arpa_TSyserr; 43: fmtmsg(MsgBuf, (char *) NULL, p, fmt, a, b, c, d, e); 44: puterrmsg(MsgBuf); 45: 46: /* determine exit status if not already set */ 47: if (ExitStat == EX_OK) 48: { 49: if (errno == 0) 50: ExitStat = EX_SOFTWARE; 51: else 52: ExitStat = EX_OSERR; 53: } 54: 55: /* insure that we have a queue id for logging */ 56: (void) queuename(CurEnv, '\0'); 57: # ifdef LOG 58: if (LogLevel > 0) 59: syslog(LOG_ERR, "%s: SYSERR: %s", CurEnv->e_id, &MsgBuf[4]); 60: # endif LOG 61: errno = 0; 62: if (QuickAbort) 63: longjmp(TopFrame, 2); 64: } 65: /* 66: ** USRERR -- Signal user error. 67: ** 68: ** This is much like syserr except it is for user errors. 69: ** 70: ** Parameters: 71: ** fmt, a, b, c, d -- printf strings 72: ** 73: ** Returns: 74: ** none 75: ** Through TopFrame if QuickAbort is set. 76: ** 77: ** Side Effects: 78: ** increments Errors. 79: */ 80: 81: /*VARARGS1*/ 82: usrerr(fmt, a, b, c, d, e) 83: char *fmt; 84: { 85: extern char SuprErrs; 86: extern char Arpa_Usrerr[]; 87: 88: if (SuprErrs) 89: return; 90: 91: fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, fmt, a, b, c, d, e); 92: puterrmsg(MsgBuf); 93: 94: if (QuickAbort) 95: longjmp(TopFrame, 1); 96: } 97: /* 98: ** MESSAGE -- print message (not necessarily an error) 99: ** 100: ** Parameters: 101: ** num -- the default ARPANET error number (in ascii) 102: ** msg -- the message (printf fmt) -- if it begins 103: ** with a digit, this number overrides num. 104: ** a, b, c, d, e -- printf arguments 105: ** 106: ** Returns: 107: ** none 108: ** 109: ** Side Effects: 110: ** none. 111: */ 112: 113: /*VARARGS2*/ 114: message(num, msg, a, b, c, d, e) 115: register char *num; 116: register char *msg; 117: { 118: errno = 0; 119: fmtmsg(MsgBuf, CurEnv->e_to, num, msg, a, b, c, d, e); 120: putmsg(MsgBuf, FALSE); 121: } 122: /* 123: ** NMESSAGE -- print message (not necessarily an error) 124: ** 125: ** Just like "message" except it never puts the to... tag on. 126: ** 127: ** Parameters: 128: ** num -- the default ARPANET error number (in ascii) 129: ** msg -- the message (printf fmt) -- if it begins 130: ** with a digit, this number overrides num. 131: ** a, b, c, d, e -- printf arguments 132: ** 133: ** Returns: 134: ** none 135: ** 136: ** Side Effects: 137: ** none. 138: */ 139: 140: /*VARARGS2*/ 141: nmessage(num, msg, a, b, c, d, e) 142: register char *num; 143: register char *msg; 144: { 145: errno = 0; 146: fmtmsg(MsgBuf, (char *) NULL, num, msg, a, b, c, d, e); 147: putmsg(MsgBuf, FALSE); 148: } 149: /* 150: ** PUTMSG -- output error message to transcript and channel 151: ** 152: ** Parameters: 153: ** msg -- message to output (in SMTP format). 154: ** holdmsg -- if TRUE, don't output a copy of the message to 155: ** our output channel. 156: ** 157: ** Returns: 158: ** none. 159: ** 160: ** Side Effects: 161: ** Outputs msg to the transcript. 162: ** If appropriate, outputs it to the channel. 163: ** Deletes SMTP reply code number as appropriate. 164: */ 165: 166: putmsg(msg, holdmsg) 167: char *msg; 168: bool holdmsg; 169: { 170: /* output to transcript */ 171: if (CurEnv->e_xfp != NULL) 172: fprintf(CurEnv->e_xfp, "%s\n", OpMode == MD_SMTP ? msg : &msg[4]); 173: 174: /* output to channel if appropriate */ 175: if (!holdmsg && (Verbose || msg[0] != '0')) 176: { 177: (void) fflush(stdout); 178: if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP) 179: fprintf(OutChannel, "%s\r\n", msg); 180: else 181: fprintf(OutChannel, "%s\n", &msg[4]); 182: (void) fflush(OutChannel); 183: } 184: } 185: /* 186: ** PUTERRMSG -- like putmsg, but does special processing for error messages 187: ** 188: ** Parameters: 189: ** msg -- the message to output. 190: ** 191: ** Returns: 192: ** none. 193: ** 194: ** Side Effects: 195: ** Sets the fatal error bit in the envelope as appropriate. 196: */ 197: 198: puterrmsg(msg) 199: char *msg; 200: { 201: /* output the message as usual */ 202: putmsg(msg, HoldErrs); 203: 204: /* signal the error */ 205: Errors++; 206: if (msg[0] == '5') 207: CurEnv->e_flags |= EF_FATALERRS; 208: } 209: /* 210: ** FMTMSG -- format a message into buffer. 211: ** 212: ** Parameters: 213: ** eb -- error buffer to get result. 214: ** to -- the recipient tag for this message. 215: ** num -- arpanet error number. 216: ** fmt -- format of string. 217: ** a, b, c, d, e -- arguments. 218: ** 219: ** Returns: 220: ** none. 221: ** 222: ** Side Effects: 223: ** none. 224: */ 225: 226: /*VARARGS4*/ 227: static 228: fmtmsg(eb, to, num, fmt, a, b, c, d, e) 229: register char *eb; 230: char *to; 231: char *num; 232: char *fmt; 233: { 234: char del; 235: 236: /* output the reply code */ 237: if (isdigit(*fmt)) 238: { 239: num = fmt; 240: fmt += 4; 241: } 242: if (num[3] == '-') 243: del = '-'; 244: else 245: del = ' '; 246: (void) sprintf(eb, "%3.3s%c", num, del); 247: eb += 4; 248: 249: /* output the file name and line number */ 250: if (FileName != NULL) 251: { 252: (void) sprintf(eb, "%s: line %d: ", FileName, LineNumber); 253: eb += strlen(eb); 254: } 255: 256: /* output the "to" person */ 257: if (to != NULL && to[0] != '\0') 258: { 259: (void) sprintf(eb, "%s... ", to); 260: while (*eb != '\0') 261: *eb++ &= 0177; 262: } 263: 264: /* output the message */ 265: (void) sprintf(eb, fmt, a, b, c, d, e); 266: while (*eb != '\0') 267: *eb++ &= 0177; 268: 269: /* output the error code, if any */ 270: if (errno != 0) 271: { 272: extern int sys_nerr; 273: extern char *sys_errlist[]; 274: if (errno < sys_nerr && errno > 0) 275: (void) sprintf(eb, ": %s", sys_errlist[errno]); 276: else 277: (void) sprintf(eb, ": error %d", errno); 278: eb += strlen(eb); 279: } 280: }