summaryrefslogtreecommitdiffstats
path: root/src/global/sys_exits.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/global/sys_exits.c')
-rw-r--r--src/global/sys_exits.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/global/sys_exits.c b/src/global/sys_exits.c
new file mode 100644
index 0000000..1e628d7
--- /dev/null
+++ b/src/global/sys_exits.c
@@ -0,0 +1,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');
+ }
+}