13311Seric # include "sendmail.h" 2295Seric 3*9108Seric SCCSID(@(#)err.c 3.31 11/07/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); 44*9108Seric 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); 91*9108Seric 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); 119*9108Seric 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); 146*9108Seric 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). 153*9108Seric ** holdmsg -- if TRUE, don't output a copy of the message to 154*9108Seric ** 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 165*9108Seric putmsg(msg, holdmsg) 1667613Seric char *msg; 167*9108Seric bool holdmsg; 1687613Seric { 1694711Seric /* output to transcript */ 1707613Seric fprintf(Xscript, "%s\n", Smtp ? msg : &msg[4]); 1714711Seric 1724711Seric /* output to channel if appropriate */ 173*9108Seric if (!holdmsg && (Verbose || msg[0] != '0')) 1744063Seric { 1757275Seric (void) fflush(stdout); 1764711Seric if (ArpaMode) 1777613Seric fprintf(OutChannel, "%s\r\n", msg); 1784711Seric else 1797613Seric fprintf(OutChannel, "%s\n", &msg[4]); 1804711Seric (void) fflush(OutChannel); 1814063Seric } 1828239Seric 1838239Seric /* determine error status */ 1848239Seric switch (msg[0]) 1858239Seric { 1868239Seric case '5': 1878239Seric FatalErrors = TRUE; 1888239Seric /* fall through.... */ 1898239Seric 1908239Seric case '4': 1918239Seric Errors++; 1928239Seric break; 1938239Seric } 1944711Seric } 1954711Seric /* 1964711Seric ** FMTMSG -- format a message into buffer. 1974711Seric ** 1984711Seric ** Parameters: 1994711Seric ** eb -- error buffer to get result. 2004711Seric ** to -- the recipient tag for this message. 2014711Seric ** num -- arpanet error number. 2024711Seric ** fmt -- format of string. 2034711Seric ** a, b, c, d, e -- arguments. 2044711Seric ** 2054711Seric ** Returns: 2064711Seric ** none. 2074711Seric ** 2084711Seric ** Side Effects: 2094711Seric ** none. 2104711Seric */ 2114063Seric 2124834Seric /*VARARGS4*/ 2134711Seric static 2144711Seric fmtmsg(eb, to, num, fmt, a, b, c, d, e) 2154711Seric register char *eb; 2164711Seric char *to; 2174711Seric char *num; 2184711Seric char *fmt; 2194711Seric { 2204711Seric char del; 2214711Seric 2224711Seric /* output the reply code */ 2234711Seric if (isdigit(*fmt)) 2244577Seric { 2254711Seric num = fmt; 2264711Seric fmt += 4; 2274711Seric } 2284711Seric if (num[3] == '-') 2294711Seric del = '-'; 2304711Seric else 2314711Seric del = ' '; 2324711Seric (void) sprintf(eb, "%3.3s%c", num, del); 2334711Seric eb += 4; 2344063Seric 2354711Seric /* output the "to" person */ 2364711Seric if (to != NULL && to[0] != '\0') 2374711Seric { 2384711Seric (void) sprintf(eb, "%s... ", to); 2395201Seric while (*eb != '\0') 2405201Seric *eb++ &= 0177; 2414711Seric } 2424711Seric 2434711Seric /* output the message */ 2444711Seric (void) sprintf(eb, fmt, a, b, c, d, e); 2455201Seric while (*eb != '\0') 2465201Seric *eb++ &= 0177; 2474711Seric 2484711Seric /* output the error code, if any */ 2494711Seric if (errno != 0) 2504711Seric { 2514711Seric extern int sys_nerr; 2524711Seric extern char *sys_errlist[]; 2534711Seric if (errno < sys_nerr && errno > 0) 2544711Seric (void) sprintf(eb, ": %s", sys_errlist[errno]); 2554577Seric else 2564711Seric (void) sprintf(eb, ": error %d", errno); 2574711Seric eb += strlen(eb); 2584577Seric } 259295Seric } 260