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