1 /*
2  * Copyright (c) 1983, 1995 Eric P. Allman
3  * Copyright (c) 1988, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * %sccs.include.redist.c%
7  */
8 
9 #ifndef lint
10 static char sccsid[] = "@(#)sysexits.c	8.5 (Berkeley) 05/24/95";
11 #endif /* not lint */
12 
13 #include <sendmail.h>
14 
15 /*
16 **  SYSEXITS.C -- error messages corresponding to sysexits.h
17 **
18 **	If the first character of the string is a colon, interpolate
19 **	the current errno after the rest of the string.
20 */
21 
22 char *SysExMsg[] =
23 {
24 	/* 64 USAGE */		" 500 Bad usage",
25 	/* 65 DATAERR */	" 501 Data format error",
26 	/* 66 NOINPUT */	":550 Cannot open input",
27 	/* 67 NOUSER */		" 550 User unknown",
28 	/* 68 NOHOST */		" 550 Host unknown",
29 	/* 69 UNAVAILABLE */	" 554 Service unavailable",
30 	/* 70 SOFTWARE */	":554 Internal error",
31 	/* 71 OSERR */		":451 Operating system error",
32 	/* 72 OSFILE */		":554 System file missing",
33 	/* 73 CANTCREAT */	":550 Can't create output",
34 	/* 74 IOERR */		":451 I/O error",
35 	/* 75 TEMPFAIL */	" 250 Deferred",
36 	/* 76 PROTOCOL */	" 554 Remote protocol error",
37 	/* 77 NOPERM */		":550 Insufficient permission",
38 	/* 78 CONFIG */		" 554 Local configuration error",
39 };
40 
41 int N_SysEx = sizeof(SysExMsg) / sizeof(SysExMsg[0]);
42 /*
43 **  DSNTOEXITSTAT -- convert DSN-style error code to EX_ style.
44 **
45 **	Parameters:
46 **		dsncode -- the text of the DSN-style code.
47 **
48 **	Returns:
49 **		The corresponding exit status.
50 */
51 
52 int
53 dsntoexitstat(dsncode)
54 	char *dsncode;
55 {
56 	int code2, code3;
57 
58 	/* first the easy cases.... */
59 	if (*dsncode == '2')
60 		return EX_OK;
61 	if (*dsncode == '4')
62 		return EX_TEMPFAIL;
63 
64 	/* now decode the other two field parts */
65 	if (*++dsncode == '.')
66 		dsncode++;
67 	code2 = atoi(dsncode);
68 	while (*dsncode != '\0' && *dsncode != '.')
69 		dsncode++;
70 	if (*dsncode != '\0')
71 		dsncode++;
72 	code3 = atoi(dsncode);
73 
74 	/* and do a nested switch to work them out */
75 	switch (code2)
76 	{
77 	  case 0:	/* Other or Undefined status */
78 		return EX_UNAVAILABLE;
79 
80 	  case 1:	/* Address Status */
81 		switch (code3)
82 		{
83 		  case 0:	/* Other Address Status */
84 			return EX_DATAERR;
85 
86 		  case 1:	/* Bad destination mailbox address */
87 		  case 6:	/* Mailbox has moved, No forwarding address */
88 			return EX_NOUSER;
89 
90 		  case 2:	/* Bad destination system address */
91 		  case 8:	/* Bad senders system address */
92 			return EX_NOHOST;
93 
94 		  case 3:	/* Bad destination mailbox address syntax */
95 		  case 7:	/* Bad senders mailbox address syntax */
96 			return EX_USAGE;
97 
98 		  case 4:	/* Destination mailbox address ambiguous */
99 			return EX_UNAVAILABLE;
100 
101 		  case 5:	/* Destination address valid */
102 			return EX_OK;
103 		}
104 		break;
105 
106 	  case 2:	/* Mailbox Status */
107 		switch (code3)
108 		{
109 		  case 0:	/* Other or Undefined mailbox status */
110 		  case 1:	/* Mailbox disabled, not acccepting messages */
111 		  case 2:	/* Mailbox full */
112 		  case 4:	/* Mailing list expansion problem */
113 			return EX_UNAVAILABLE;
114 
115 		  case 3:	/* Message length exceeds administrative lim */
116 			return EX_DATAERR;
117 		}
118 		break;
119 
120 	  case 3:	/* System Status */
121 		return EX_OSERR;
122 
123 	  case 4:	/* Network and Routing Status */
124 		switch (code3)
125 		{
126 		  case 0:	/* Other or undefined network or routing stat */
127 			return EX_IOERR;
128 
129 		  case 1:	/* No answer from host */
130 		  case 3:	/* Routing server failure */
131 		  case 5:	/* Network congestion */
132 			return EX_TEMPFAIL;
133 
134 		  case 2:	/* Bad connection */
135 			return EX_IOERR;
136 
137 		  case 4:	/* Unable to route */
138 			return EX_PROTOCOL;
139 
140 		  case 6:	/* Routing loop detected */
141 			return EX_CONFIG;
142 
143 		  case 7:	/* Delivery time expired */
144 			return EX_UNAVAILABLE;
145 		}
146 		break;
147 
148 	  case 5:	/* Protocol Status */
149 		return EX_PROTOCOL;
150 
151 	  case 6:	/* Message Content or Media Status */
152 		return EX_UNAVAILABLE;
153 
154 	  case 7:	/* Security Status */
155 		return EX_DATAERR;
156 	}
157 	return EX_CONFIG;
158 }
159