13311Seric # include "sendmail.h" 2295Seric 3*9277Seric SCCSID(@(#)err.c 3.33 11/17/82); 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 287525Seric static 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); 449108Seric putmsg(MsgBuf, HoldErrs); 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 557810Seric (void) queuename(CurEnv, '\0'); 56295Seric # ifdef LOG 577674Seric if (LogLevel > 0) 587810Seric syslog(LOG_ERR, "%s: %s", CurEnv->e_id, &MsgBuf[4]); 59295Seric # endif LOG 60295Seric errno = 0; 617762Seric if (QuickAbort) 627762Seric longjmp(TopFrame, 2); 63295Seric } 64295Seric /* 65295Seric ** USRERR -- Signal user error. 66295Seric ** 67295Seric ** This is much like syserr except it is for user errors. 68295Seric ** 69295Seric ** Parameters: 70295Seric ** fmt, a, b, c, d -- printf strings 71295Seric ** 72295Seric ** Returns: 734084Seric ** none 747762Seric ** Through TopFrame if QuickAbort is set. 75295Seric ** 76295Seric ** Side Effects: 771514Seric ** increments Errors. 78295Seric */ 79295Seric 80295Seric /*VARARGS1*/ 81295Seric usrerr(fmt, a, b, c, d, e) 82295Seric char *fmt; 83295Seric { 84295Seric extern char SuprErrs; 854167Seric extern char Arpa_Usrerr[]; 86295Seric 87295Seric if (SuprErrs) 884084Seric return; 89295Seric 907613Seric fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, fmt, a, b, c, d, e); 919108Seric putmsg(MsgBuf, HoldErrs); 928239Seric 937762Seric if (QuickAbort) 947762Seric longjmp(TopFrame, 1); 954063Seric } 964063Seric /* 974063Seric ** MESSAGE -- print message (not necessarily an error) 984063Seric ** 994063Seric ** Parameters: 1004063Seric ** num -- the default ARPANET error number (in ascii) 1014063Seric ** msg -- the message (printf fmt) -- if it begins 1024063Seric ** with a digit, this number overrides num. 1034063Seric ** a, b, c, d, e -- printf arguments 1044063Seric ** 1054063Seric ** Returns: 1064063Seric ** none 1074063Seric ** 1084063Seric ** Side Effects: 1094063Seric ** none. 1104063Seric */ 1114063Seric 1124084Seric /*VARARGS2*/ 1134063Seric message(num, msg, a, b, c, d, e) 1144063Seric register char *num; 1154063Seric register char *msg; 1164063Seric { 1174711Seric errno = 0; 1187525Seric fmtmsg(MsgBuf, CurEnv->e_to, num, msg, a, b, c, d, e); 1199108Seric putmsg(MsgBuf, FALSE); 1207613Seric } 1217613Seric /* 1228239Seric ** NMESSAGE -- print message (not necessarily an error) 1238239Seric ** 1248239Seric ** Just like "message" except it never puts the to... tag on. 1258239Seric ** 1268239Seric ** Parameters: 1278239Seric ** num -- the default ARPANET error number (in ascii) 1288239Seric ** msg -- the message (printf fmt) -- if it begins 1298239Seric ** with a digit, this number overrides num. 1308239Seric ** a, b, c, d, e -- printf arguments 1318239Seric ** 1328239Seric ** Returns: 1338239Seric ** none 1348239Seric ** 1358239Seric ** Side Effects: 1368239Seric ** none. 1378239Seric */ 1388239Seric 1398239Seric /*VARARGS2*/ 1408239Seric nmessage(num, msg, a, b, c, d, e) 1418239Seric register char *num; 1428239Seric register char *msg; 1438239Seric { 1448239Seric errno = 0; 1458239Seric fmtmsg(MsgBuf, NULL, num, msg, a, b, c, d, e); 1469108Seric putmsg(MsgBuf, FALSE); 1478239Seric } 1488239Seric /* 1497613Seric ** PUTMSG -- output error message to transcript and channel 1507613Seric ** 1517613Seric ** Parameters: 1527613Seric ** msg -- message to output (in SMTP format). 1539108Seric ** holdmsg -- if TRUE, don't output a copy of the message to 1549108Seric ** our output channel. 1557613Seric ** 1567613Seric ** Returns: 1577613Seric ** none. 1587613Seric ** 1597613Seric ** Side Effects: 1607613Seric ** Outputs msg to the transcript. 1617613Seric ** If appropriate, outputs it to the channel. 1627613Seric ** Deletes SMTP reply code number as appropriate. 1637613Seric */ 1644711Seric 1659108Seric putmsg(msg, holdmsg) 1667613Seric char *msg; 1679108Seric bool holdmsg; 1687613Seric { 1694711Seric /* output to transcript */ 1709143Seric if (Xscript != OutChannel) 171*9277Seric fprintf(Xscript, "%s\n", OpMode == MD_SMTP ? msg : &msg[4]); 1724711Seric 1734711Seric /* output to channel if appropriate */ 1749108Seric if (!holdmsg && (Verbose || msg[0] != '0')) 1754063Seric { 1767275Seric (void) fflush(stdout); 177*9277Seric if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP) 1787613Seric fprintf(OutChannel, "%s\r\n", msg); 1794711Seric else 1807613Seric fprintf(OutChannel, "%s\n", &msg[4]); 1814711Seric (void) fflush(OutChannel); 1824063Seric } 1838239Seric 1848239Seric /* determine error status */ 1858239Seric switch (msg[0]) 1868239Seric { 1878239Seric case '5': 1888239Seric FatalErrors = TRUE; 1898239Seric /* fall through.... */ 1908239Seric 1918239Seric case '4': 1928239Seric Errors++; 1938239Seric break; 1948239Seric } 1954711Seric } 1964711Seric /* 1974711Seric ** FMTMSG -- format a message into buffer. 1984711Seric ** 1994711Seric ** Parameters: 2004711Seric ** eb -- error buffer to get result. 2014711Seric ** to -- the recipient tag for this message. 2024711Seric ** num -- arpanet error number. 2034711Seric ** fmt -- format of string. 2044711Seric ** a, b, c, d, e -- arguments. 2054711Seric ** 2064711Seric ** Returns: 2074711Seric ** none. 2084711Seric ** 2094711Seric ** Side Effects: 2104711Seric ** none. 2114711Seric */ 2124063Seric 2134834Seric /*VARARGS4*/ 2144711Seric static 2154711Seric fmtmsg(eb, to, num, fmt, a, b, c, d, e) 2164711Seric register char *eb; 2174711Seric char *to; 2184711Seric char *num; 2194711Seric char *fmt; 2204711Seric { 2214711Seric char del; 2224711Seric 2234711Seric /* output the reply code */ 2244711Seric if (isdigit(*fmt)) 2254577Seric { 2264711Seric num = fmt; 2274711Seric fmt += 4; 2284711Seric } 2294711Seric if (num[3] == '-') 2304711Seric del = '-'; 2314711Seric else 2324711Seric del = ' '; 2334711Seric (void) sprintf(eb, "%3.3s%c", num, del); 2344711Seric eb += 4; 2354063Seric 2364711Seric /* output the "to" person */ 2374711Seric if (to != NULL && to[0] != '\0') 2384711Seric { 2394711Seric (void) sprintf(eb, "%s... ", to); 2405201Seric while (*eb != '\0') 2415201Seric *eb++ &= 0177; 2424711Seric } 2434711Seric 2444711Seric /* output the message */ 2454711Seric (void) sprintf(eb, fmt, a, b, c, d, e); 2465201Seric while (*eb != '\0') 2475201Seric *eb++ &= 0177; 2484711Seric 2494711Seric /* output the error code, if any */ 2504711Seric if (errno != 0) 2514711Seric { 2524711Seric extern int sys_nerr; 2534711Seric extern char *sys_errlist[]; 2544711Seric if (errno < sys_nerr && errno > 0) 2554711Seric (void) sprintf(eb, ": %s", sys_errlist[errno]); 2564577Seric else 2574711Seric (void) sprintf(eb, ": error %d", errno); 2584711Seric eb += strlen(eb); 2594577Seric } 260295Seric } 261