13311Seric # include "sendmail.h" 2295Seric 3*14900Seric SCCSID(@(#)err.c 4.2 09/05/83); 4406Seric 5295Seric /* 61514Seric ** SYSERR -- Print error message. 7295Seric ** 8295Seric ** Prints an error message via printf to the diagnostic 9295Seric ** output. If LOG is defined, it logs it also. 10295Seric ** 11295Seric ** Parameters: 12295Seric ** f -- the format string 13295Seric ** a, b, c, d, e -- parameters 14295Seric ** 15295Seric ** Returns: 164084Seric ** none 177762Seric ** Through TopFrame if QuickAbort is set. 18295Seric ** 19295Seric ** Side Effects: 201514Seric ** increments Errors. 211514Seric ** sets ExitStat. 22295Seric */ 23295Seric 244084Seric # ifdef lint 254084Seric int sys_nerr; 264084Seric char *sys_errlist[]; 274084Seric # endif lint 2810147Seric char MsgBuf[BUFSIZ*2]; /* text of most recent message */ 294084Seric 30295Seric /*VARARGS1*/ 31295Seric syserr(fmt, a, b, c, d, e) 32295Seric char *fmt; 33295Seric { 347957Seric extern char Arpa_PSyserr[]; 357957Seric extern char Arpa_TSyserr[]; 367957Seric register char *p; 37295Seric 387525Seric /* format and output the error message */ 397957Seric if (errno == 0) 407957Seric p = Arpa_PSyserr; 417957Seric else 427957Seric p = Arpa_TSyserr; 437957Seric fmtmsg(MsgBuf, (char *) NULL, p, fmt, a, b, c, d, e); 449389Seric puterrmsg(MsgBuf); 454063Seric 46295Seric /* determine exit status if not already set */ 47295Seric if (ExitStat == EX_OK) 48295Seric { 49295Seric if (errno == 0) 50295Seric ExitStat = EX_SOFTWARE; 51295Seric else 521598Seric ExitStat = EX_OSERR; 53295Seric } 54295Seric 559372Seric /* insure that we have a queue id for logging */ 567810Seric (void) queuename(CurEnv, '\0'); 57295Seric # ifdef LOG 587674Seric if (LogLevel > 0) 5910050Seric syslog(LOG_ERR, "%s: SYSERR: %s", CurEnv->e_id, &MsgBuf[4]); 60295Seric # endif LOG 61295Seric errno = 0; 627762Seric if (QuickAbort) 637762Seric longjmp(TopFrame, 2); 64295Seric } 65295Seric /* 66295Seric ** USRERR -- Signal user error. 67295Seric ** 68295Seric ** This is much like syserr except it is for user errors. 69295Seric ** 70295Seric ** Parameters: 71295Seric ** fmt, a, b, c, d -- printf strings 72295Seric ** 73295Seric ** Returns: 744084Seric ** none 757762Seric ** Through TopFrame if QuickAbort is set. 76295Seric ** 77295Seric ** Side Effects: 781514Seric ** increments Errors. 79295Seric */ 80295Seric 81295Seric /*VARARGS1*/ 82295Seric usrerr(fmt, a, b, c, d, e) 83295Seric char *fmt; 84295Seric { 85295Seric extern char SuprErrs; 864167Seric extern char Arpa_Usrerr[]; 87295Seric 88295Seric if (SuprErrs) 894084Seric return; 90295Seric 917613Seric fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, fmt, a, b, c, d, e); 929389Seric puterrmsg(MsgBuf); 938239Seric 947762Seric if (QuickAbort) 957762Seric longjmp(TopFrame, 1); 964063Seric } 974063Seric /* 984063Seric ** MESSAGE -- print message (not necessarily an error) 994063Seric ** 1004063Seric ** Parameters: 1014063Seric ** num -- the default ARPANET error number (in ascii) 1024063Seric ** msg -- the message (printf fmt) -- if it begins 1034063Seric ** with a digit, this number overrides num. 1044063Seric ** a, b, c, d, e -- printf arguments 1054063Seric ** 1064063Seric ** Returns: 1074063Seric ** none 1084063Seric ** 1094063Seric ** Side Effects: 1104063Seric ** none. 1114063Seric */ 1124063Seric 1134084Seric /*VARARGS2*/ 1144063Seric message(num, msg, a, b, c, d, e) 1154063Seric register char *num; 1164063Seric register char *msg; 1174063Seric { 1184711Seric errno = 0; 1197525Seric fmtmsg(MsgBuf, CurEnv->e_to, num, msg, a, b, c, d, e); 1209108Seric putmsg(MsgBuf, FALSE); 1217613Seric } 1227613Seric /* 1238239Seric ** NMESSAGE -- print message (not necessarily an error) 1248239Seric ** 1258239Seric ** Just like "message" except it never puts the to... tag on. 1268239Seric ** 1278239Seric ** Parameters: 1288239Seric ** num -- the default ARPANET error number (in ascii) 1298239Seric ** msg -- the message (printf fmt) -- if it begins 1308239Seric ** with a digit, this number overrides num. 1318239Seric ** a, b, c, d, e -- printf arguments 1328239Seric ** 1338239Seric ** Returns: 1348239Seric ** none 1358239Seric ** 1368239Seric ** Side Effects: 1378239Seric ** none. 1388239Seric */ 1398239Seric 1408239Seric /*VARARGS2*/ 1418239Seric nmessage(num, msg, a, b, c, d, e) 1428239Seric register char *num; 1438239Seric register char *msg; 1448239Seric { 1458239Seric errno = 0; 1469346Seric fmtmsg(MsgBuf, (char *) NULL, num, msg, a, b, c, d, e); 1479108Seric putmsg(MsgBuf, FALSE); 1488239Seric } 1498239Seric /* 1507613Seric ** PUTMSG -- output error message to transcript and channel 1517613Seric ** 1527613Seric ** Parameters: 1537613Seric ** msg -- message to output (in SMTP format). 1549108Seric ** holdmsg -- if TRUE, don't output a copy of the message to 1559108Seric ** our output channel. 1567613Seric ** 1577613Seric ** Returns: 1587613Seric ** none. 1597613Seric ** 1607613Seric ** Side Effects: 1617613Seric ** Outputs msg to the transcript. 1627613Seric ** If appropriate, outputs it to the channel. 1637613Seric ** Deletes SMTP reply code number as appropriate. 1647613Seric */ 1654711Seric 1669108Seric putmsg(msg, holdmsg) 1677613Seric char *msg; 1689108Seric bool holdmsg; 1697613Seric { 170*14900Seric /* output to transcript if serious */ 171*14900Seric if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5')) 172*14900Seric fprintf(CurEnv->e_xfp, "%s\n", msg); 1734711Seric 1744711Seric /* output to channel if appropriate */ 1759108Seric if (!holdmsg && (Verbose || msg[0] != '0')) 1764063Seric { 1777275Seric (void) fflush(stdout); 1789277Seric if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP) 1797613Seric fprintf(OutChannel, "%s\r\n", msg); 1804711Seric else 1817613Seric fprintf(OutChannel, "%s\n", &msg[4]); 1824711Seric (void) fflush(OutChannel); 1834063Seric } 1849389Seric } 1859389Seric /* 1869389Seric ** PUTERRMSG -- like putmsg, but does special processing for error messages 1879389Seric ** 1889389Seric ** Parameters: 1899389Seric ** msg -- the message to output. 1909389Seric ** 1919389Seric ** Returns: 1929389Seric ** none. 1939389Seric ** 1949389Seric ** Side Effects: 1959389Seric ** Sets the fatal error bit in the envelope as appropriate. 1969389Seric */ 1978239Seric 1989389Seric puterrmsg(msg) 1999389Seric char *msg; 2009389Seric { 2019389Seric /* output the message as usual */ 2029389Seric putmsg(msg, HoldErrs); 2039389Seric 2049389Seric /* signal the error */ 2059389Seric Errors++; 2069389Seric if (msg[0] == '5') 2079336Seric CurEnv->e_flags |= EF_FATALERRS; 2084711Seric } 2094711Seric /* 2104711Seric ** FMTMSG -- format a message into buffer. 2114711Seric ** 2124711Seric ** Parameters: 2134711Seric ** eb -- error buffer to get result. 2144711Seric ** to -- the recipient tag for this message. 2154711Seric ** num -- arpanet error number. 2164711Seric ** fmt -- format of string. 2174711Seric ** a, b, c, d, e -- arguments. 2184711Seric ** 2194711Seric ** Returns: 2204711Seric ** none. 2214711Seric ** 2224711Seric ** Side Effects: 2234711Seric ** none. 2244711Seric */ 2254063Seric 2264834Seric /*VARARGS4*/ 2274711Seric static 2284711Seric fmtmsg(eb, to, num, fmt, a, b, c, d, e) 2294711Seric register char *eb; 2304711Seric char *to; 2314711Seric char *num; 2324711Seric char *fmt; 2334711Seric { 2344711Seric char del; 2354711Seric 2364711Seric /* output the reply code */ 2374711Seric if (isdigit(*fmt)) 2384577Seric { 2394711Seric num = fmt; 2404711Seric fmt += 4; 2414711Seric } 2424711Seric if (num[3] == '-') 2434711Seric del = '-'; 2444711Seric else 2454711Seric del = ' '; 2464711Seric (void) sprintf(eb, "%3.3s%c", num, del); 2474711Seric eb += 4; 2484063Seric 2499372Seric /* output the file name and line number */ 2509372Seric if (FileName != NULL) 2519372Seric { 2529372Seric (void) sprintf(eb, "%s: line %d: ", FileName, LineNumber); 2539372Seric eb += strlen(eb); 2549372Seric } 2559372Seric 2564711Seric /* output the "to" person */ 2574711Seric if (to != NULL && to[0] != '\0') 2584711Seric { 2594711Seric (void) sprintf(eb, "%s... ", to); 2605201Seric while (*eb != '\0') 2615201Seric *eb++ &= 0177; 2624711Seric } 2634711Seric 2644711Seric /* output the message */ 2654711Seric (void) sprintf(eb, fmt, a, b, c, d, e); 2665201Seric while (*eb != '\0') 2675201Seric *eb++ &= 0177; 2684711Seric 2694711Seric /* output the error code, if any */ 2704711Seric if (errno != 0) 2714711Seric { 2724711Seric extern int sys_nerr; 2734711Seric extern char *sys_errlist[]; 2744711Seric if (errno < sys_nerr && errno > 0) 2754711Seric (void) sprintf(eb, ": %s", sys_errlist[errno]); 2764577Seric else 2774711Seric (void) sprintf(eb, ": error %d", errno); 2784711Seric eb += strlen(eb); 2794577Seric } 280295Seric } 281