1: /*
   2: **  Sendmail
   3: **  Copyright (c) 1983  Eric P. Allman
   4: **  Berkeley, California
   5: **
   6: **  Copyright (c) 1983 Regents of the University of California.
   7: **  All rights reserved.  The Berkeley software License Agreement
   8: **  specifies the terms and conditions for redistribution.
   9: */
  10: 
  11: #if !defined(lint) && !defined(NOSCCS)
  12: static char SccsId[] = "@(#)err.c	5.7.1 (2.11BSD GTE) 7/14/94";
  13: #endif
  14: 
  15: # include "sendmail.h"
  16: # include <errno.h>
  17: # include <netdb.h>
  18: # include <string.h>
  19: 
  20: /*
  21: **  SYSERR -- Print error message.
  22: **
  23: **	Prints an error message via printf to the diagnostic
  24: **	output.  If LOG is defined, it logs it also.
  25: **
  26: **	Parameters:
  27: **		f -- the format string
  28: **		a, b, c, d, e -- parameters
  29: **
  30: **	Returns:
  31: **		none
  32: **		Through TopFrame if QuickAbort is set.
  33: **
  34: **	Side Effects:
  35: **		increments Errors.
  36: **		sets ExitStat.
  37: */
  38: 
  39: char    MsgBuf[BUFSIZ*2];   /* text of most recent message */
  40: 
  41: /*VARARGS1*/
  42: syserr(fmt, a, b, c, d, e)
  43:     char *fmt;
  44: {
  45:     register char *p;
  46:     int olderrno = errno;
  47: 
  48:     /* format and output the error message */
  49:     if (olderrno == 0)
  50:         p = Arpa_PSyserr;
  51:     else
  52:         p = Arpa_TSyserr;
  53:     fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, a, b, c, d, e);
  54:     puterrmsg(MsgBuf);
  55: 
  56:     /* determine exit status if not already set */
  57:     if (ExitStat == EX_OK)
  58:     {
  59:         if (olderrno == 0)
  60:             ExitStat = EX_SOFTWARE;
  61:         else
  62:             ExitStat = EX_OSERR;
  63:     }
  64: 
  65: # ifdef LOG
  66:     if (LogLevel > 0)
  67:         syslog(LOG_CRIT, "%s: SYSERR: %s",
  68:             CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
  69:             &MsgBuf[4]);
  70: # endif LOG
  71:     errno = 0;
  72:     if (QuickAbort)
  73:         longjmp(TopFrame, 2);
  74: }
  75: /*
  76: **  USRERR -- Signal user error.
  77: **
  78: **	This is much like syserr except it is for user errors.
  79: **
  80: **	Parameters:
  81: **		fmt, a, b, c, d -- printf strings
  82: **
  83: **	Returns:
  84: **		none
  85: **		Through TopFrame if QuickAbort is set.
  86: **
  87: **	Side Effects:
  88: **		increments Errors.
  89: */
  90: 
  91: /*VARARGS1*/
  92: usrerr(fmt, a, b, c, d, e)
  93:     char *fmt;
  94: {
  95:     extern char SuprErrs;
  96:     extern int errno;
  97: 
  98:     if (SuprErrs)
  99:         return;
 100: 
 101:     fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, errno, fmt, a, b, c, d, e);
 102:     puterrmsg(MsgBuf);
 103: 
 104:     if (QuickAbort)
 105:         longjmp(TopFrame, 1);
 106: }
 107: /*
 108: **  MESSAGE -- print message (not necessarily an error)
 109: **
 110: **	Parameters:
 111: **		num -- the default ARPANET error number (in ascii)
 112: **		msg -- the message (printf fmt) -- if it begins
 113: **			with a digit, this number overrides num.
 114: **		a, b, c, d, e -- printf arguments
 115: **
 116: **	Returns:
 117: **		none
 118: **
 119: **	Side Effects:
 120: **		none.
 121: */
 122: 
 123: /*VARARGS2*/
 124: message(num, msg, a, b, c, d, e)
 125:     register char *num;
 126:     register char *msg;
 127: {
 128:     errno = 0;
 129:     fmtmsg(MsgBuf, CurEnv->e_to, num, 0, msg, a, b, c, d, e);
 130:     putmsg(MsgBuf, FALSE);
 131: }
 132: /*
 133: **  NMESSAGE -- print message (not necessarily an error)
 134: **
 135: **	Just like "message" except it never puts the to... tag on.
 136: **
 137: **	Parameters:
 138: **		num -- the default ARPANET error number (in ascii)
 139: **		msg -- the message (printf fmt) -- if it begins
 140: **			with three digits, this number overrides num.
 141: **		a, b, c, d, e -- printf arguments
 142: **
 143: **	Returns:
 144: **		none
 145: **
 146: **	Side Effects:
 147: **		none.
 148: */
 149: 
 150: /*VARARGS2*/
 151: nmessage(num, msg, a, b, c, d, e)
 152:     register char *num;
 153:     register char *msg;
 154: {
 155:     errno = 0;
 156:     fmtmsg(MsgBuf, (char *) NULL, num, 0, msg, a, b, c, d, e);
 157:     putmsg(MsgBuf, FALSE);
 158: }
 159: /*
 160: **  PUTMSG -- output error message to transcript and channel
 161: **
 162: **	Parameters:
 163: **		msg -- message to output (in SMTP format).
 164: **		holdmsg -- if TRUE, don't output a copy of the message to
 165: **			our output channel.
 166: **
 167: **	Returns:
 168: **		none.
 169: **
 170: **	Side Effects:
 171: **		Outputs msg to the transcript.
 172: **		If appropriate, outputs it to the channel.
 173: **		Deletes SMTP reply code number as appropriate.
 174: */
 175: 
 176: putmsg(msg, holdmsg)
 177:     char *msg;
 178:     bool holdmsg;
 179: {
 180:     /* output to transcript if serious */
 181:     if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5'))
 182:         fprintf(CurEnv->e_xfp, "%s\n", msg);
 183: 
 184:     /* output to channel if appropriate */
 185:     if (!holdmsg && (Verbose || msg[0] != '0'))
 186:     {
 187:         (void) fflush(stdout);
 188:         if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
 189:             fprintf(OutChannel, "%s\r\n", msg);
 190:         else
 191:             fprintf(OutChannel, "%s\n", &msg[4]);
 192:         (void) fflush(OutChannel);
 193:     }
 194: }
 195: /*
 196: **  PUTERRMSG -- like putmsg, but does special processing for error messages
 197: **
 198: **	Parameters:
 199: **		msg -- the message to output.
 200: **
 201: **	Returns:
 202: **		none.
 203: **
 204: **	Side Effects:
 205: **		Sets the fatal error bit in the envelope as appropriate.
 206: */
 207: 
 208: puterrmsg(msg)
 209:     char *msg;
 210: {
 211:     /* output the message as usual */
 212:     putmsg(msg, HoldErrs);
 213: 
 214:     /* signal the error */
 215:     Errors++;
 216:     if (msg[0] == '5')
 217:         CurEnv->e_flags |= EF_FATALERRS;
 218: }
 219: /*
 220: **  FMTMSG -- format a message into buffer.
 221: **
 222: **	Parameters:
 223: **		eb -- error buffer to get result.
 224: **		to -- the recipient tag for this message.
 225: **		num -- arpanet error number.
 226: **		en -- the error number to display.
 227: **		fmt -- format of string.
 228: **		a, b, c, d, e -- arguments.
 229: **
 230: **	Returns:
 231: **		none.
 232: **
 233: **	Side Effects:
 234: **		none.
 235: */
 236: 
 237: /*VARARGS5*/
 238: static
 239: fmtmsg(eb, to, num, eno, fmt, a, b, c, d, e)
 240:     register char *eb;
 241:     char *to;
 242:     char *num;
 243:     int eno;
 244:     char *fmt;
 245: {
 246:     char del;
 247: 
 248:     /* output the reply code */
 249:     if (isdigit(fmt[0]) && isdigit(fmt[1]) && isdigit(fmt[2]))
 250:     {
 251:         num = fmt;
 252:         fmt += 4;
 253:     }
 254:     if (num[3] == '-')
 255:         del = '-';
 256:     else
 257:         del = ' ';
 258:     (void) sprintf(eb, "%3.3s%c", num, del);
 259:     eb += 4;
 260: 
 261:     /* output the file name and line number */
 262:     if (FileName != NULL)
 263:     {
 264:         (void) sprintf(eb, "%s: line %d: ", FileName, LineNumber);
 265:         eb += strlen(eb);
 266:     }
 267: 
 268:     /* output the "to" person */
 269:     if (to != NULL && to[0] != '\0')
 270:     {
 271:         (void) sprintf(eb, "%s... ", to);
 272:         while (*eb != '\0')
 273:             *eb++ &= 0177;
 274:     }
 275: 
 276:     /* output the message */
 277:     (void) sprintf(eb, fmt, a, b, c, d, e);
 278:     while (*eb != '\0')
 279:         *eb++ &= 0177;
 280: 
 281:     /* output the error code, if any */
 282:     if (eno != 0)
 283:     {
 284:         extern char *errstring();
 285: 
 286:         (void) sprintf(eb, ": %s", errstring(eno));
 287:         eb += strlen(eb);
 288:     }
 289: }
 290: /*
 291: **  ERRSTRING -- return string description of error code
 292: **
 293: **	Parameters:
 294: **		errno -- the error number to translate
 295: **
 296: **	Returns:
 297: **		A string description of errno.
 298: **
 299: **	Side Effects:
 300: **		none.
 301: */
 302: 
 303: char *
 304: errstring(errno)
 305:     int errno;
 306: {
 307:     static char buf[100];
 308: # ifdef SMTP
 309:     extern char *SmtpPhase;
 310: # endif SMTP
 311: 
 312: # ifdef DAEMON
 313: # ifdef VMUNIX
 314:     /*
 315: 	**  Handle special network error codes.
 316: 	**
 317: 	**	These are 4.2/4.3bsd specific; they should be in daemon.c.
 318: 	*/
 319: 
 320:     switch (errno)
 321:     {
 322:       case ETIMEDOUT:
 323:       case ECONNRESET:
 324:         (void) strcpy(buf, strerror(errno));
 325:         if (SmtpPhase != NULL)
 326:         {
 327:             (void) strcat(buf, " during ");
 328:             (void) strcat(buf, SmtpPhase);
 329:         }
 330:         if (CurHostName != NULL)
 331:         {
 332:             (void) strcat(buf, " with ");
 333:             (void) strcat(buf, CurHostName);
 334:         }
 335:         return (buf);
 336: 
 337:       case EHOSTDOWN:
 338:         if (CurHostName == NULL)
 339:             break;
 340:         (void) sprintf(buf, "Host %s is down", CurHostName);
 341:         return (buf);
 342: 
 343:       case ECONNREFUSED:
 344:         if (CurHostName == NULL)
 345:             break;
 346:         (void) sprintf(buf, "Connection refused by %s", CurHostName);
 347:         return (buf);
 348: 
 349:       case (TRY_AGAIN+MAX_ERRNO):
 350:         (void) sprintf(buf, "Host Name Lookup Failure");
 351:         return (buf);
 352:     }
 353: # endif VMUNIX
 354: # endif DAEMON
 355: 
 356:     return (strerror(errno));
 357: }

Defined functions

fmtmsg defined in line 238; used 4 times
puterrmsg defined in line 208; used 2 times
putmsg defined in line 176; used 3 times

Defined variables

MsgBuf defined in line 39; used 9 times
SccsId defined in line 12; never used
Last modified: 1994-07-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3932
Valid CSS Valid XHTML 1.0 Strict