1/* $NetBSD: sys_exits.c,v 1.2 2017/02/14 01:16:45 christos 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/* The generic entry may be overwritten with each sys_exits_detail() 45/* call. 46/* 47/* sys_exits_softerror() returns non-zero when the specified 48/* sendmail-compatible status code corresponds to a recoverable error. 49/* An unknown status code is always unrecoverable. 50/* DIAGNOSTICS 51/* Fatal: out of memory. 52/* LICENSE 53/* .ad 54/* .fi 55/* The Secure Mailer license must be distributed with this software. 56/* AUTHOR(S) 57/* Wietse Venema 58/* IBM T.J. Watson Research 59/* P.O. Box 704 60/* Yorktown Heights, NY 10598, USA 61/*--*/ 62 63/* System library. */ 64 65#include <sys_defs.h> 66 67/* Utility library. */ 68 69#include <msg.h> 70#include <vstring.h> 71 72/* Global library. */ 73 74#include <sys_exits.h> 75 76/* Application-specific. */ 77 78static const SYS_EXITS_DETAIL sys_exits_table[] = { 79 EX_USAGE, "5.3.0", "command line usage error", 80 EX_DATAERR, "5.6.0", "data format error", 81 EX_NOINPUT, "5.3.0", "cannot open input", 82 EX_NOUSER, "5.1.1", "user unknown", 83 EX_NOHOST, "5.1.2", "host name unknown", 84 EX_UNAVAILABLE, "5.3.0", "service unavailable", 85 EX_SOFTWARE, "5.3.0", "internal software error", 86 EX_OSERR, "4.3.0", "system resource problem", 87 EX_OSFILE, "5.3.0", "critical OS file missing", 88 EX_CANTCREAT, "5.2.0", "can't create user output file", 89 EX_IOERR, "5.3.0", "input/output error", 90 EX_TEMPFAIL, "4.3.0", "temporary failure", 91 EX_PROTOCOL, "5.5.0", "remote error in protocol", 92 EX_NOPERM, "5.7.0", "permission denied", 93 EX_CONFIG, "5.3.5", "local configuration error", 94}; 95 96static VSTRING *sys_exits_def_text = 0; 97 98static SYS_EXITS_DETAIL sys_exits_default[] = { 99 0, "5.3.0", 0, 100}; 101 102/* sys_exits_fake - fake an entry for an unknown code */ 103 104static SYS_EXITS_DETAIL *sys_exits_fake(int code) 105{ 106 if (sys_exits_def_text == 0) 107 sys_exits_def_text = vstring_alloc(30); 108 109 vstring_sprintf(sys_exits_def_text, "unknown mail system error %d", code); 110 sys_exits_default->text = vstring_str(sys_exits_def_text); 111 return (sys_exits_default); 112} 113 114/* sys_exits_strerror - map exit status to error string */ 115 116const char *sys_exits_strerror(int code) 117{ 118 if (!SYS_EXITS_CODE(code)) { 119 return (sys_exits_fake(code)->text); 120 } else { 121 return (sys_exits_table[code - EX__BASE].text); 122 } 123} 124 125/* sys_exits_detail - map exit status info table entry */ 126 127const SYS_EXITS_DETAIL *sys_exits_detail(int code) 128{ 129 if (!SYS_EXITS_CODE(code)) { 130 return (sys_exits_fake(code)); 131 } else { 132 return (sys_exits_table + code - EX__BASE); 133 } 134} 135 136/* sys_exits_softerror - determine if error is transient */ 137 138int sys_exits_softerror(int code) 139{ 140 if (!SYS_EXITS_CODE(code)) { 141 return (sys_exits_default->dsn[0] == '4'); 142 } else { 143 return (sys_exits_table[code - EX__BASE].dsn[0] == '4'); 144 } 145} 146