xref: /freebsd/contrib/sendmail/src/sysexits.c (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
1 /*
2  * Copyright (c) 1998-2001 Proofpoint, Inc. and its suppliers.
3  *	All rights reserved.
4  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5  * Copyright (c) 1988, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * By using this file, you agree to the terms and conditions set
9  * forth in the LICENSE file which can be found at the top level of
10  * the sendmail distribution.
11  *
12  */
13 
14 #include <sendmail.h>
15 
16 SM_RCSID("@(#)$Id: sysexits.c,v 8.35 2013-11-22 20:51:57 ca Exp $")
17 
18 /*
19 **  DSNTOEXITSTAT -- convert DSN-style error code to EX_ style.
20 **
21 **	Parameters:
22 **		dsncode -- the text of the DSN-style code.
23 **
24 **	Returns:
25 **		The corresponding exit status.
26 */
27 
28 int
29 dsntoexitstat(dsncode)
30 	char *dsncode;
31 {
32 	int code2, code3;
33 
34 	/* first the easy cases.... */
35 	if (*dsncode == '2')
36 		return EX_OK;
37 	if (*dsncode == '4')
38 		return EX_TEMPFAIL;
39 
40 	/* reject other illegal values */
41 	if (*dsncode != '5')
42 		return EX_CONFIG;
43 
44 	/* now decode the other two field parts */
45 	if (*++dsncode == '.')
46 		dsncode++;
47 	code2 = atoi(dsncode);
48 	while (*dsncode != '\0' && *dsncode != '.')
49 		dsncode++;
50 	if (*dsncode != '\0')
51 		dsncode++;
52 	code3 = atoi(dsncode);
53 
54 	/* and do a nested switch to work them out */
55 	switch (code2)
56 	{
57 	  case 0:	/* Other or Undefined status */
58 		return EX_UNAVAILABLE;
59 
60 	  case 1:	/* Address Status */
61 		switch (code3)
62 		{
63 		  case 0:	/* Other Address Status */
64 			return EX_DATAERR;
65 
66 		  case 1:	/* Bad destination mailbox address */
67 		  case 6:	/* Mailbox has moved, No forwarding address */
68 			return EX_NOUSER;
69 
70 		  case 2:	/* Bad destination system address */
71 		  case 8:	/* Bad senders system address */
72 			return EX_NOHOST;
73 
74 		  case 3:	/* Bad destination mailbox address syntax */
75 		  case 7:	/* Bad senders mailbox address syntax */
76 			return EX_USAGE;
77 
78 		  case 4:	/* Destination mailbox address ambiguous */
79 			return EX_UNAVAILABLE;
80 
81 		  case 5:	/* Destination address valid */
82 			/* According to RFC1893, this can't happen */
83 			return EX_CONFIG;
84 		}
85 		break;
86 
87 	  case 2:	/* Mailbox Status */
88 		switch (code3)
89 		{
90 		  case 0:	/* Other or Undefined mailbox status */
91 		  case 1:	/* Mailbox disabled, not accepting messages */
92 		  case 2:	/* Mailbox full */
93 		  case 4:	/* Mailing list expansion problem */
94 			return EX_UNAVAILABLE;
95 
96 		  case 3:	/* Message length exceeds administrative lim */
97 			return EX_DATAERR;
98 		}
99 		break;
100 
101 	  case 3:	/* System Status */
102 		return EX_OSERR;
103 
104 	  case 4:	/* Network and Routing Status */
105 		switch (code3)
106 		{
107 		  case 0:	/* Other or undefined network or routing stat */
108 			return EX_IOERR;
109 
110 		  case 1:	/* No answer from host */
111 		  case 3:	/* Routing server failure */
112 		  case 5:	/* Network congestion */
113 			return EX_TEMPFAIL;
114 
115 		  case 2:	/* Bad connection */
116 			return EX_IOERR;
117 
118 		  case 4:	/* Unable to route */
119 			return EX_PROTOCOL;
120 
121 		  case 6:	/* Routing loop detected */
122 			return EX_CONFIG;
123 
124 		  case 7:	/* Delivery time expired */
125 			return EX_UNAVAILABLE;
126 		}
127 		break;
128 
129 	  case 5:	/* Protocol Status */
130 		return EX_PROTOCOL;
131 
132 	  case 6:	/* Message Content or Media Status */
133 		return EX_UNAVAILABLE;
134 
135 	  case 7:	/* Security Status */
136 		return EX_DATAERR;
137 	}
138 	return EX_UNAVAILABLE;
139 }
140 /*
141 **  EXITSTAT -- convert EX_ value to error text.
142 **
143 **	Parameters:
144 **		excode -- rstatus which might consists of an EX_* value.
145 **
146 **	Returns:
147 **		The corresponding error text or the original string.
148 */
149 
150 char *
151 exitstat(excode)
152 	char *excode;
153 {
154 	char *c;
155 	int i;
156 	char *exitmsg;
157 
158 	if (excode == NULL || *excode == '\0')
159 		return excode;
160 	i = (int) strtol(excode, &c, 10);
161 	if (*c != '\0')
162 		return excode;
163 	exitmsg = sm_sysexitmsg(i);
164 	if (exitmsg != NULL)
165 		return exitmsg;
166 	return excode;
167 }
168