13311Seric # include "sendmail.h" 2295Seric 3*16901Seric SCCSID(@(#)err.c 4.4 08/11/84); 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 { 34*16901Seric register char *p; 35*16901Seric int olderrno = errno; 367957Seric extern char Arpa_PSyserr[]; 377957Seric extern char Arpa_TSyserr[]; 38295Seric 397525Seric /* format and output the error message */ 40*16901Seric if (olderrno == 0) 417957Seric p = Arpa_PSyserr; 427957Seric else 437957Seric p = Arpa_TSyserr; 44*16901Seric fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, a, b, c, d, e); 459389Seric puterrmsg(MsgBuf); 464063Seric 47295Seric /* determine exit status if not already set */ 48295Seric if (ExitStat == EX_OK) 49295Seric { 50*16901Seric if (olderrno == 0) 51295Seric ExitStat = EX_SOFTWARE; 52295Seric else 531598Seric ExitStat = EX_OSERR; 54295Seric } 55295Seric 569372Seric /* insure that we have a queue id for logging */ 577810Seric (void) queuename(CurEnv, '\0'); 58295Seric # ifdef LOG 597674Seric if (LogLevel > 0) 6010050Seric syslog(LOG_ERR, "%s: SYSERR: %s", CurEnv->e_id, &MsgBuf[4]); 61295Seric # endif LOG 62295Seric errno = 0; 637762Seric if (QuickAbort) 647762Seric longjmp(TopFrame, 2); 65295Seric } 66295Seric /* 67295Seric ** USRERR -- Signal user error. 68295Seric ** 69295Seric ** This is much like syserr except it is for user errors. 70295Seric ** 71295Seric ** Parameters: 72295Seric ** fmt, a, b, c, d -- printf strings 73295Seric ** 74295Seric ** Returns: 754084Seric ** none 767762Seric ** Through TopFrame if QuickAbort is set. 77295Seric ** 78295Seric ** Side Effects: 791514Seric ** increments Errors. 80295Seric */ 81295Seric 82295Seric /*VARARGS1*/ 83295Seric usrerr(fmt, a, b, c, d, e) 84295Seric char *fmt; 85295Seric { 86295Seric extern char SuprErrs; 874167Seric extern char Arpa_Usrerr[]; 88*16901Seric extern int errno; 89295Seric 90295Seric if (SuprErrs) 914084Seric return; 92295Seric 93*16901Seric fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, errno, fmt, a, b, c, d, e); 949389Seric puterrmsg(MsgBuf); 958239Seric 967762Seric if (QuickAbort) 977762Seric longjmp(TopFrame, 1); 984063Seric } 994063Seric /* 1004063Seric ** MESSAGE -- print message (not necessarily an error) 1014063Seric ** 1024063Seric ** Parameters: 1034063Seric ** num -- the default ARPANET error number (in ascii) 1044063Seric ** msg -- the message (printf fmt) -- if it begins 1054063Seric ** with a digit, this number overrides num. 1064063Seric ** a, b, c, d, e -- printf arguments 1074063Seric ** 1084063Seric ** Returns: 1094063Seric ** none 1104063Seric ** 1114063Seric ** Side Effects: 1124063Seric ** none. 1134063Seric */ 1144063Seric 1154084Seric /*VARARGS2*/ 1164063Seric message(num, msg, a, b, c, d, e) 1174063Seric register char *num; 1184063Seric register char *msg; 1194063Seric { 1204711Seric errno = 0; 121*16901Seric fmtmsg(MsgBuf, CurEnv->e_to, num, 0, msg, a, b, c, d, e); 1229108Seric putmsg(MsgBuf, FALSE); 1237613Seric } 1247613Seric /* 1258239Seric ** NMESSAGE -- print message (not necessarily an error) 1268239Seric ** 1278239Seric ** Just like "message" except it never puts the to... tag on. 1288239Seric ** 1298239Seric ** Parameters: 1308239Seric ** num -- the default ARPANET error number (in ascii) 1318239Seric ** msg -- the message (printf fmt) -- if it begins 1328239Seric ** with a digit, this number overrides num. 1338239Seric ** a, b, c, d, e -- printf arguments 1348239Seric ** 1358239Seric ** Returns: 1368239Seric ** none 1378239Seric ** 1388239Seric ** Side Effects: 1398239Seric ** none. 1408239Seric */ 1418239Seric 1428239Seric /*VARARGS2*/ 1438239Seric nmessage(num, msg, a, b, c, d, e) 1448239Seric register char *num; 1458239Seric register char *msg; 1468239Seric { 1478239Seric errno = 0; 148*16901Seric fmtmsg(MsgBuf, (char *) NULL, num, 0, msg, a, b, c, d, e); 1499108Seric putmsg(MsgBuf, FALSE); 1508239Seric } 1518239Seric /* 1527613Seric ** PUTMSG -- output error message to transcript and channel 1537613Seric ** 1547613Seric ** Parameters: 1557613Seric ** msg -- message to output (in SMTP format). 1569108Seric ** holdmsg -- if TRUE, don't output a copy of the message to 1579108Seric ** our output channel. 1587613Seric ** 1597613Seric ** Returns: 1607613Seric ** none. 1617613Seric ** 1627613Seric ** Side Effects: 1637613Seric ** Outputs msg to the transcript. 1647613Seric ** If appropriate, outputs it to the channel. 1657613Seric ** Deletes SMTP reply code number as appropriate. 1667613Seric */ 1674711Seric 1689108Seric putmsg(msg, holdmsg) 1697613Seric char *msg; 1709108Seric bool holdmsg; 1717613Seric { 17214900Seric /* output to transcript if serious */ 17314900Seric if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5')) 17414900Seric fprintf(CurEnv->e_xfp, "%s\n", msg); 1754711Seric 1764711Seric /* output to channel if appropriate */ 1779108Seric if (!holdmsg && (Verbose || msg[0] != '0')) 1784063Seric { 1797275Seric (void) fflush(stdout); 1809277Seric if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP) 1817613Seric fprintf(OutChannel, "%s\r\n", msg); 1824711Seric else 1837613Seric fprintf(OutChannel, "%s\n", &msg[4]); 1844711Seric (void) fflush(OutChannel); 1854063Seric } 1869389Seric } 1879389Seric /* 1889389Seric ** PUTERRMSG -- like putmsg, but does special processing for error messages 1899389Seric ** 1909389Seric ** Parameters: 1919389Seric ** msg -- the message to output. 1929389Seric ** 1939389Seric ** Returns: 1949389Seric ** none. 1959389Seric ** 1969389Seric ** Side Effects: 1979389Seric ** Sets the fatal error bit in the envelope as appropriate. 1989389Seric */ 1998239Seric 2009389Seric puterrmsg(msg) 2019389Seric char *msg; 2029389Seric { 2039389Seric /* output the message as usual */ 2049389Seric putmsg(msg, HoldErrs); 2059389Seric 2069389Seric /* signal the error */ 2079389Seric Errors++; 2089389Seric if (msg[0] == '5') 2099336Seric CurEnv->e_flags |= EF_FATALERRS; 2104711Seric } 2114711Seric /* 2124711Seric ** FMTMSG -- format a message into buffer. 2134711Seric ** 2144711Seric ** Parameters: 2154711Seric ** eb -- error buffer to get result. 2164711Seric ** to -- the recipient tag for this message. 2174711Seric ** num -- arpanet error number. 218*16901Seric ** en -- the error number to display. 2194711Seric ** fmt -- format of string. 2204711Seric ** a, b, c, d, e -- arguments. 2214711Seric ** 2224711Seric ** Returns: 2234711Seric ** none. 2244711Seric ** 2254711Seric ** Side Effects: 2264711Seric ** none. 2274711Seric */ 2284063Seric 229*16901Seric /*VARARGS5*/ 2304711Seric static 231*16901Seric fmtmsg(eb, to, num, eno, fmt, a, b, c, d, e) 2324711Seric register char *eb; 2334711Seric char *to; 2344711Seric char *num; 235*16901Seric int en; 2364711Seric char *fmt; 2374711Seric { 2384711Seric char del; 2394711Seric 2404711Seric /* output the reply code */ 2414711Seric if (isdigit(*fmt)) 2424577Seric { 2434711Seric num = fmt; 2444711Seric fmt += 4; 2454711Seric } 2464711Seric if (num[3] == '-') 2474711Seric del = '-'; 2484711Seric else 2494711Seric del = ' '; 2504711Seric (void) sprintf(eb, "%3.3s%c", num, del); 2514711Seric eb += 4; 2524063Seric 2539372Seric /* output the file name and line number */ 2549372Seric if (FileName != NULL) 2559372Seric { 2569372Seric (void) sprintf(eb, "%s: line %d: ", FileName, LineNumber); 2579372Seric eb += strlen(eb); 2589372Seric } 2599372Seric 2604711Seric /* output the "to" person */ 2614711Seric if (to != NULL && to[0] != '\0') 2624711Seric { 2634711Seric (void) sprintf(eb, "%s... ", to); 2645201Seric while (*eb != '\0') 2655201Seric *eb++ &= 0177; 2664711Seric } 2674711Seric 2684711Seric /* output the message */ 2694711Seric (void) sprintf(eb, fmt, a, b, c, d, e); 2705201Seric while (*eb != '\0') 2715201Seric *eb++ &= 0177; 2724711Seric 2734711Seric /* output the error code, if any */ 2744711Seric if (errno != 0) 2754711Seric { 27615136Seric extern char *errstring(); 27715136Seric 27815136Seric (void) sprintf(eb, ": %s", errstring(errno)); 2794711Seric eb += strlen(eb); 2804577Seric } 281295Seric } 28215136Seric /* 28315136Seric ** ERRSTRING -- return string description of error code 28415136Seric ** 28515136Seric ** Parameters: 28615136Seric ** errno -- the error number to translate 28715136Seric ** 28815136Seric ** Returns: 28915136Seric ** A string description of errno. 29015136Seric ** 29115136Seric ** Side Effects: 29215136Seric ** none. 29315136Seric */ 29415136Seric 29515136Seric char * 29615136Seric errstring(errno) 29715136Seric int errno; 29815136Seric { 29915136Seric extern char *sys_errlist[]; 30015136Seric extern int sys_nerr; 30115136Seric static char buf[50]; 30215136Seric 30315136Seric if (errno > 0 && errno < sys_nerr) 30415136Seric return (sys_errlist[errno]); 30515136Seric 30615136Seric (void) sprintf(buf, "Error %d", errno); 30715136Seric return (buf); 30815136Seric } 309