1 /* 2 * Copyright (c) 1998, 1999 Sendmail, 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 #ifndef lint 15 static char id[] = "@(#)$Id: sysexits.c,v 8.25 1999/09/23 19:59:24 ca Exp $"; 16 #endif /* ! lint */ 17 18 #include <sendmail.h> 19 20 /* 21 ** SYSEXITS.C -- error messages corresponding to sysexits.h 22 ** 23 ** If the first character of the string is a colon, interpolate 24 ** the current errno after the rest of the string. 25 */ 26 27 char *SysExMsg[] = 28 { 29 /* 64 USAGE */ " 500 5.0.0 Bad usage", 30 /* 65 DATAERR */ " 501 5.6.0 Data format error", 31 /* 66 NOINPUT */ ":550 5.3.0 Cannot open input", 32 /* 67 NOUSER */ " 550 5.1.1 User unknown", 33 /* 68 NOHOST */ " 550 5.1.2 Host unknown", 34 /* 69 UNAVAILABLE */ " 554 5.0.0 Service unavailable", 35 /* 70 SOFTWARE */ ":554 5.3.0 Internal error", 36 /* 71 OSERR */ ":451 4.0.0 Operating system error", 37 /* 72 OSFILE */ ":554 5.3.5 System file missing", 38 /* 73 CANTCREAT */ ":550 5.0.0 Can't create output", 39 /* 74 IOERR */ ":451 4.0.0 I/O error", 40 /* 75 TEMPFAIL */ " 450 4.0.0 Deferred", 41 /* 76 PROTOCOL */ " 554 5.5.0 Remote protocol error", 42 /* 77 NOPERM */ ":550 5.0.0 Insufficient permission", 43 /* 78 CONFIG */ " 554 5.3.5 Local configuration error", 44 }; 45 46 int N_SysEx = sizeof(SysExMsg) / sizeof(SysExMsg[0]); 47 48 static char *SysExitMsg[] = 49 { 50 "command line usage error", 51 "data format error", 52 "cannot open input", 53 "addressee unknown", 54 "host name unknown", 55 "service unavailable", 56 "internal software error", 57 "system error (e.g., can't fork)", 58 "critical OS file missing", 59 "can't create (user) output file", 60 "input/output error", 61 "temp failure; user is invited to retry", 62 "remote error in protocol", 63 "permission denied", 64 "configuration error" 65 }; 66 67 /* 68 ** DSNTOEXITSTAT -- convert DSN-style error code to EX_ style. 69 ** 70 ** Parameters: 71 ** dsncode -- the text of the DSN-style code. 72 ** 73 ** Returns: 74 ** The corresponding exit status. 75 */ 76 77 int 78 dsntoexitstat(dsncode) 79 char *dsncode; 80 { 81 int code2, code3; 82 83 /* first the easy cases.... */ 84 if (*dsncode == '2') 85 return EX_OK; 86 if (*dsncode == '4') 87 return EX_TEMPFAIL; 88 89 /* now decode the other two field parts */ 90 if (*++dsncode == '.') 91 dsncode++; 92 code2 = atoi(dsncode); 93 while (*dsncode != '\0' && *dsncode != '.') 94 dsncode++; 95 if (*dsncode != '\0') 96 dsncode++; 97 code3 = atoi(dsncode); 98 99 /* and do a nested switch to work them out */ 100 switch (code2) 101 { 102 case 0: /* Other or Undefined status */ 103 return EX_UNAVAILABLE; 104 105 case 1: /* Address Status */ 106 switch (code3) 107 { 108 case 0: /* Other Address Status */ 109 return EX_DATAERR; 110 111 case 1: /* Bad destination mailbox address */ 112 case 6: /* Mailbox has moved, No forwarding address */ 113 return EX_NOUSER; 114 115 case 2: /* Bad destination system address */ 116 case 8: /* Bad senders system address */ 117 return EX_NOHOST; 118 119 case 3: /* Bad destination mailbox address syntax */ 120 case 7: /* Bad senders mailbox address syntax */ 121 return EX_USAGE; 122 123 case 4: /* Destination mailbox address ambiguous */ 124 return EX_UNAVAILABLE; 125 126 case 5: /* Destination address valid */ 127 return EX_OK; 128 } 129 break; 130 131 case 2: /* Mailbox Status */ 132 switch (code3) 133 { 134 case 0: /* Other or Undefined mailbox status */ 135 case 1: /* Mailbox disabled, not accepting messages */ 136 case 2: /* Mailbox full */ 137 case 4: /* Mailing list expansion problem */ 138 return EX_UNAVAILABLE; 139 140 case 3: /* Message length exceeds administrative lim */ 141 return EX_DATAERR; 142 } 143 break; 144 145 case 3: /* System Status */ 146 return EX_OSERR; 147 148 case 4: /* Network and Routing Status */ 149 switch (code3) 150 { 151 case 0: /* Other or undefined network or routing stat */ 152 return EX_IOERR; 153 154 case 1: /* No answer from host */ 155 case 3: /* Routing server failure */ 156 case 5: /* Network congestion */ 157 return EX_TEMPFAIL; 158 159 case 2: /* Bad connection */ 160 return EX_IOERR; 161 162 case 4: /* Unable to route */ 163 return EX_PROTOCOL; 164 165 case 6: /* Routing loop detected */ 166 return EX_CONFIG; 167 168 case 7: /* Delivery time expired */ 169 return EX_UNAVAILABLE; 170 } 171 break; 172 173 case 5: /* Protocol Status */ 174 return EX_PROTOCOL; 175 176 case 6: /* Message Content or Media Status */ 177 return EX_UNAVAILABLE; 178 179 case 7: /* Security Status */ 180 return EX_DATAERR; 181 } 182 return EX_CONFIG; 183 } 184 185 /* 186 ** EXITSTAT -- convert EX_ value to error text. 187 ** 188 ** Parameters: 189 ** excode -- rstatus which might consists of an EX_* value. 190 ** 191 ** Returns: 192 ** The corresponding error text or the original string. 193 */ 194 195 char * 196 exitstat(excode) 197 char *excode; 198 { 199 char *c; 200 int i; 201 202 if (excode == NULL || *excode == '\0') 203 return excode; 204 i = 0; 205 for (c = excode; *c != '\0'; c++) 206 { 207 if (isascii(*c) && isdigit(*c)) 208 i = i * 10 + (*c - '0'); 209 else 210 return excode; 211 } 212 i -= EX__BASE; 213 if (i >= 0 && i <= N_SysEx) 214 return SysExitMsg[i]; 215 return excode; 216 } 217