138032Speter/*
2261194Sgshapiro * Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers.
364562Sgshapiro *	All rights reserved.
438032Speter * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
538032Speter * Copyright (c) 1988, 1993
638032Speter *	The Regents of the University of California.  All rights reserved.
738032Speter *
838032Speter * By using this file, you agree to the terms and conditions set
938032Speter * forth in the LICENSE file which can be found at the top level of
1038032Speter * the sendmail distribution.
1138032Speter *
1238032Speter */
1338032Speter
1464562Sgshapiro#include <sendmail.h>
1538032Speter
16266527SgshapiroSM_RCSID("@(#)$Id: sysexits.c,v 8.35 2013-11-22 20:51:57 ca Exp $")
1790792Sgshapiro
1838032Speter/*
1938032Speter**  DSNTOEXITSTAT -- convert DSN-style error code to EX_ style.
2038032Speter**
2138032Speter**	Parameters:
2238032Speter**		dsncode -- the text of the DSN-style code.
2338032Speter**
2438032Speter**	Returns:
2538032Speter**		The corresponding exit status.
2638032Speter*/
2738032Speter
2838032Speterint
2938032Speterdsntoexitstat(dsncode)
3038032Speter	char *dsncode;
3138032Speter{
3238032Speter	int code2, code3;
3338032Speter
3438032Speter	/* first the easy cases.... */
3538032Speter	if (*dsncode == '2')
3638032Speter		return EX_OK;
3738032Speter	if (*dsncode == '4')
3838032Speter		return EX_TEMPFAIL;
3938032Speter
40110560Sgshapiro	/* reject other illegal values */
41110560Sgshapiro	if (*dsncode != '5')
42110560Sgshapiro		return EX_CONFIG;
43110560Sgshapiro
4438032Speter	/* now decode the other two field parts */
4538032Speter	if (*++dsncode == '.')
4638032Speter		dsncode++;
4738032Speter	code2 = atoi(dsncode);
4838032Speter	while (*dsncode != '\0' && *dsncode != '.')
4938032Speter		dsncode++;
5038032Speter	if (*dsncode != '\0')
5138032Speter		dsncode++;
5238032Speter	code3 = atoi(dsncode);
5338032Speter
5438032Speter	/* and do a nested switch to work them out */
5538032Speter	switch (code2)
5638032Speter	{
5738032Speter	  case 0:	/* Other or Undefined status */
5838032Speter		return EX_UNAVAILABLE;
5938032Speter
6038032Speter	  case 1:	/* Address Status */
6138032Speter		switch (code3)
6238032Speter		{
6338032Speter		  case 0:	/* Other Address Status */
6438032Speter			return EX_DATAERR;
6538032Speter
6638032Speter		  case 1:	/* Bad destination mailbox address */
6738032Speter		  case 6:	/* Mailbox has moved, No forwarding address */
6838032Speter			return EX_NOUSER;
6938032Speter
7038032Speter		  case 2:	/* Bad destination system address */
7138032Speter		  case 8:	/* Bad senders system address */
7238032Speter			return EX_NOHOST;
7338032Speter
7438032Speter		  case 3:	/* Bad destination mailbox address syntax */
7538032Speter		  case 7:	/* Bad senders mailbox address syntax */
7638032Speter			return EX_USAGE;
7738032Speter
7838032Speter		  case 4:	/* Destination mailbox address ambiguous */
7938032Speter			return EX_UNAVAILABLE;
8038032Speter
8138032Speter		  case 5:	/* Destination address valid */
82110560Sgshapiro			/* According to RFC1893, this can't happen */
83110560Sgshapiro			return EX_CONFIG;
8438032Speter		}
8538032Speter		break;
8638032Speter
8738032Speter	  case 2:	/* Mailbox Status */
8838032Speter		switch (code3)
8938032Speter		{
9038032Speter		  case 0:	/* Other or Undefined mailbox status */
9164562Sgshapiro		  case 1:	/* Mailbox disabled, not accepting messages */
9238032Speter		  case 2:	/* Mailbox full */
9338032Speter		  case 4:	/* Mailing list expansion problem */
9438032Speter			return EX_UNAVAILABLE;
9538032Speter
9638032Speter		  case 3:	/* Message length exceeds administrative lim */
9738032Speter			return EX_DATAERR;
9838032Speter		}
9938032Speter		break;
10038032Speter
10138032Speter	  case 3:	/* System Status */
10238032Speter		return EX_OSERR;
10338032Speter
10438032Speter	  case 4:	/* Network and Routing Status */
10538032Speter		switch (code3)
10638032Speter		{
10738032Speter		  case 0:	/* Other or undefined network or routing stat */
10838032Speter			return EX_IOERR;
10938032Speter
11038032Speter		  case 1:	/* No answer from host */
11138032Speter		  case 3:	/* Routing server failure */
11238032Speter		  case 5:	/* Network congestion */
11338032Speter			return EX_TEMPFAIL;
11438032Speter
11538032Speter		  case 2:	/* Bad connection */
11638032Speter			return EX_IOERR;
11738032Speter
11838032Speter		  case 4:	/* Unable to route */
11938032Speter			return EX_PROTOCOL;
12038032Speter
12138032Speter		  case 6:	/* Routing loop detected */
12238032Speter			return EX_CONFIG;
12338032Speter
12438032Speter		  case 7:	/* Delivery time expired */
12538032Speter			return EX_UNAVAILABLE;
12638032Speter		}
12738032Speter		break;
12838032Speter
12938032Speter	  case 5:	/* Protocol Status */
13038032Speter		return EX_PROTOCOL;
13138032Speter
13238032Speter	  case 6:	/* Message Content or Media Status */
13338032Speter		return EX_UNAVAILABLE;
13438032Speter
13538032Speter	  case 7:	/* Security Status */
13638032Speter		return EX_DATAERR;
13738032Speter	}
138110560Sgshapiro	return EX_UNAVAILABLE;
13938032Speter}
14090792Sgshapiro/*
14164562Sgshapiro**  EXITSTAT -- convert EX_ value to error text.
14264562Sgshapiro**
14364562Sgshapiro**	Parameters:
14464562Sgshapiro**		excode -- rstatus which might consists of an EX_* value.
14564562Sgshapiro**
14664562Sgshapiro**	Returns:
14764562Sgshapiro**		The corresponding error text or the original string.
14864562Sgshapiro*/
14964562Sgshapiro
15064562Sgshapirochar *
15164562Sgshapiroexitstat(excode)
15264562Sgshapiro	char *excode;
15364562Sgshapiro{
15464562Sgshapiro	char *c;
15564562Sgshapiro	int i;
15690792Sgshapiro	char *exitmsg;
15764562Sgshapiro
15864562Sgshapiro	if (excode == NULL || *excode == '\0')
15964562Sgshapiro		return excode;
16090792Sgshapiro	i = (int) strtol(excode, &c, 10);
16190792Sgshapiro	if (*c != '\0')
16290792Sgshapiro		return excode;
16390792Sgshapiro	exitmsg = sm_sysexitmsg(i);
16490792Sgshapiro	if (exitmsg != NULL)
16590792Sgshapiro		return exitmsg;
16664562Sgshapiro	return excode;
16764562Sgshapiro}
168