summaryrefslogtreecommitdiffstats
path: root/src/global/sys_exits.c
blob: 1e628d785db3c09f1552ac9c6bc324112dc2a47e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*++
/* NAME
/*	sys_exits 3
/* SUMMARY
/*	sendmail-compatible exit status handling
/* SYNOPSIS
/*	#include <sys_exits.h>
/*
/*	typedef struct {
/* .in +4
/*	    int   status;	/* exit status */
/*	    const char *dsn;	/* RFC 3463 */
/*	    const char *text;	/* free text */
/* .in -4
/*	} SYS_EXITS_DETAIL;
/*
/*	int	SYS_EXITS_CODE(code)
/*	int	code;
/*
/*	const char *sys_exits_strerror(code)
/*	int	code;
/*
/*	const SYS_EXITS_DETAIL *sys_exits_detail(code)
/*	int	code;
/*
/*	int	sys_exits_softerror(code)
/*	int	code;
/* DESCRIPTION
/*	This module interprets sendmail-compatible process exit status
/*	codes.
/*
/*	SYS_EXITS_CODE() returns non-zero when the specified code
/*	is a sendmail-compatible process exit status code.
/*
/*	sys_exits_strerror() returns a descriptive text for the
/*	specified sendmail-compatible status code, or a generic
/*	text for an unknown status code.
/*
/*	sys_exits_detail() returns a table entry with assorted
/*	information about the specified sendmail-compatible status
/*	code, or a generic entry for an unknown status code.
/*	The generic entry may be overwritten with each sys_exits_detail()
/*	call.
/*
/*	sys_exits_softerror() returns non-zero when the specified
/*	sendmail-compatible status code corresponds to a recoverable error.
/*	An unknown status code is always unrecoverable.
/* DIAGNOSTICS
/*	Fatal: out of memory.
/* LICENSE
/* .ad
/* .fi
/*	The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/*	Wietse Venema
/*	IBM T.J. Watson Research
/*	P.O. Box 704
/*	Yorktown Heights, NY 10598, USA
/*--*/

/* System library. */

#include <sys_defs.h>

/* Utility library. */

#include <msg.h>
#include <vstring.h>

/* Global library. */

#include <sys_exits.h>

/* Application-specific. */

static const SYS_EXITS_DETAIL sys_exits_table[] = {
    EX_USAGE, "5.3.0", "command line usage error",
    EX_DATAERR, "5.6.0", "data format error",
    EX_NOINPUT, "5.3.0", "cannot open input",
    EX_NOUSER, "5.1.1", "user unknown",
    EX_NOHOST, "5.1.2", "host name unknown",
    EX_UNAVAILABLE, "5.3.0", "service unavailable",
    EX_SOFTWARE, "5.3.0", "internal software error",
    EX_OSERR, "4.3.0", "system resource problem",
    EX_OSFILE, "5.3.0", "critical OS file missing",
    EX_CANTCREAT, "5.2.0", "can't create user output file",
    EX_IOERR, "5.3.0", "input/output error",
    EX_TEMPFAIL, "4.3.0", "temporary failure",
    EX_PROTOCOL, "5.5.0", "remote error in protocol",
    EX_NOPERM, "5.7.0", "permission denied",
    EX_CONFIG, "5.3.5", "local configuration error",
};

static VSTRING *sys_exits_def_text = 0;

static SYS_EXITS_DETAIL sys_exits_default[] = {
    0, "5.3.0", 0,
};

/* sys_exits_fake - fake an entry for an unknown code */

static SYS_EXITS_DETAIL *sys_exits_fake(int code)
{
    if (sys_exits_def_text == 0)
	sys_exits_def_text = vstring_alloc(30);

    vstring_sprintf(sys_exits_def_text, "unknown mail system error %d", code);
    sys_exits_default->text = vstring_str(sys_exits_def_text);
    return (sys_exits_default);
}

/* sys_exits_strerror - map exit status to error string */

const char *sys_exits_strerror(int code)
{
    if (!SYS_EXITS_CODE(code)) {
	return (sys_exits_fake(code)->text);
    } else {
	return (sys_exits_table[code - EX__BASE].text);
    }
}

/* sys_exits_detail - map exit status info table entry */

const SYS_EXITS_DETAIL *sys_exits_detail(int code)
{
    if (!SYS_EXITS_CODE(code)) {
	return (sys_exits_fake(code));
    } else {
	return (sys_exits_table + code - EX__BASE);
    }
}

/* sys_exits_softerror  - determine if error is transient */

int     sys_exits_softerror(int code)
{
    if (!SYS_EXITS_CODE(code)) {
	return (sys_exits_default->dsn[0] == '4');
    } else {
	return (sys_exits_table[code - EX__BASE].dsn[0] == '4');
    }
}