1/*++ 2/* NAME 3/* sys_exits 3 4/* SUMMARY 5/* sendmail-compatible exit status handling 6/* SYNOPSIS 7/* #include <sys_exits.h> 8/* 9/* typedef struct { 10/* .in +4 11/* int status; /* exit status */ 12/* const char *dsn; /* RFC 3463 */ 13/* const char *text; /* free text */ 14/* .in -4 15/* } SYS_EXITS_DETAIL; 16/* 17/* int SYS_EXITS_CODE(code) 18/* int code; 19/* 20/* const char *sys_exits_strerror(code) 21/* int code; 22/* 23/* const SYS_EXITS_DETAIL *sys_exits_detail(code) 24/* int code; 25/* 26/* int sys_exits_softerror(code) 27/* int code; 28/* DESCRIPTION 29/* This module interprets sendmail-compatible process exit status 30/* codes. 31/* 32/* SYS_EXITS_CODE() returns non-zero when the specified code 33/* is a sendmail-compatible process exit status code. 34/* 35/* sys_exits_strerror() returns a descriptive text for the 36/* specified sendmail-compatible status code, or a generic 37/* text for an unknown status code. 38/* 39/* sys_exits_detail() returns a table entry with assorted 40/* information about the specified sendmail-compatible status 41/* code, or a generic entry for an unknown status code. 42/* The generic entry may be overwritten with each sys_exits_detail() 43/* call. 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 76static 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 94static VSTRING *sys_exits_def_text = 0; 95 96static 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 102static 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 114const 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 125const 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 136int 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