1 /* $NetBSD: sys_exits.c,v 1.1.1.1 2009/06/23 10:08:48 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* sys_exits 3 6 /* SUMMARY 7 /* sendmail-compatible exit status handling 8 /* SYNOPSIS 9 /* #include <sys_exits.h> 10 /* 11 /* typedef struct { 12 /* .in +4 13 /* int status; /* exit status */ 14 /* const char *dsn; /* RFC 3463 */ 15 /* const char *text; /* free text */ 16 /* .in -4 17 /* } SYS_EXITS_DETAIL; 18 /* 19 /* int SYS_EXITS_CODE(code) 20 /* int code; 21 /* 22 /* const char *sys_exits_strerror(code) 23 /* int code; 24 /* 25 /* const SYS_EXITS_DETAIL *sys_exits_detail(code) 26 /* int code; 27 /* 28 /* int sys_exits_softerror(code) 29 /* int code; 30 /* DESCRIPTION 31 /* This module interprets sendmail-compatible process exit status 32 /* codes. 33 /* 34 /* SYS_EXITS_CODE() returns non-zero when the specified code 35 /* is a sendmail-compatible process exit status code. 36 /* 37 /* sys_exits_strerror() returns a descriptive text for the 38 /* specified sendmail-compatible status code, or a generic 39 /* text for an unknown status code. 40 /* 41 /* sys_exits_detail() returns a table entry with assorted 42 /* information about the specified sendmail-compatible status 43 /* code, or a generic entry for an unknown status code. 44 /* 45 /* sys_exits_softerror() returns non-zero when the specified 46 /* sendmail-compatible status code corresponds to a recoverable error. 47 /* An unknown status code is always unrecoverable. 48 /* DIAGNOSTICS 49 /* Fatal: out of memory. 50 /* LICENSE 51 /* .ad 52 /* .fi 53 /* The Secure Mailer license must be distributed with this software. 54 /* AUTHOR(S) 55 /* Wietse Venema 56 /* IBM T.J. Watson Research 57 /* P.O. Box 704 58 /* Yorktown Heights, NY 10598, USA 59 /*--*/ 60 61 /* System library. */ 62 63 #include <sys_defs.h> 64 65 /* Utility library. */ 66 67 #include <msg.h> 68 #include <vstring.h> 69 70 /* Global library. */ 71 72 #include <sys_exits.h> 73 74 /* Application-specific. */ 75 76 static const SYS_EXITS_DETAIL sys_exits_table[] = { 77 EX_USAGE, "5.3.0", "command line usage error", 78 EX_DATAERR, "5.6.0", "data format error", 79 EX_NOINPUT, "5.3.0", "cannot open input", 80 EX_NOUSER, "5.1.1", "user unknown", 81 EX_NOHOST, "5.1.2", "host name unknown", 82 EX_UNAVAILABLE, "5.3.0", "service unavailable", 83 EX_SOFTWARE, "5.3.0", "internal software error", 84 EX_OSERR, "4.3.0", "system resource problem", 85 EX_OSFILE, "5.3.0", "critical OS file missing", 86 EX_CANTCREAT, "5.2.0", "can't create user output file", 87 EX_IOERR, "5.3.0", "input/output error", 88 EX_TEMPFAIL, "4.3.0", "temporary failure", 89 EX_PROTOCOL, "5.5.0", "remote error in protocol", 90 EX_NOPERM, "5.7.0", "permission denied", 91 EX_CONFIG, "5.3.5", "local configuration error", 92 }; 93 94 static VSTRING *sys_exits_def_text = 0; 95 96 static SYS_EXITS_DETAIL sys_exits_default[] = { 97 0, "5.3.0", 0, 98 }; 99 100 /* sys_exits_fake - fake an entry for an unknown code */ 101 102 static SYS_EXITS_DETAIL *sys_exits_fake(int code) 103 { 104 if (sys_exits_def_text == 0) 105 sys_exits_def_text = vstring_alloc(30); 106 107 vstring_sprintf(sys_exits_def_text, "unknown mail system error %d", code); 108 sys_exits_default->text = vstring_str(sys_exits_def_text); 109 return(sys_exits_default); 110 } 111 112 /* sys_exits_strerror - map exit status to error string */ 113 114 const char *sys_exits_strerror(int code) 115 { 116 if (!SYS_EXITS_CODE(code)) { 117 return (sys_exits_fake(code)->text); 118 } else { 119 return (sys_exits_table[code - EX__BASE].text); 120 } 121 } 122 123 /* sys_exits_detail - map exit status info table entry */ 124 125 const SYS_EXITS_DETAIL *sys_exits_detail(int code) 126 { 127 if (!SYS_EXITS_CODE(code)) { 128 return (sys_exits_fake(code)); 129 } else { 130 return (sys_exits_table + code - EX__BASE); 131 } 132 } 133 134 /* sys_exits_softerror - determine if error is transient */ 135 136 int sys_exits_softerror(int code) 137 { 138 if (!SYS_EXITS_CODE(code)) { 139 return (sys_exits_default->dsn[0] == '4'); 140 } else { 141 return (sys_exits_table[code - EX__BASE].dsn[0] == '4'); 142 } 143 } 144