Home | History | Annotate | Line # | Download | only in global
      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 
     78 static 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 
     96 static VSTRING *sys_exits_def_text = 0;
     97 
     98 static 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 
    104 static 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 
    116 const 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 
    127 const 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 
    138 int     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