xref: /netbsd-src/external/ibm-public/postfix/dist/src/global/dsn.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1 /*	$NetBSD: dsn.c,v 1.2 2017/02/14 01:16:45 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	dsn
6 /* SUMMARY
7 /*	RFC-compliant delivery status information
8 /* SYNOPSIS
9 /*	#include <dsn.h>
10 /*
11 /*	typedef struct {
12 /* .in +4
13 /*		const char *status;	/* RFC 3463 status */
14 /*		const char *action;	/* null or RFC 3464 action */
15 /*		const char *reason;	/* human-readable text */
16 /*		const char *dtype;	/* null or diagnostic type */
17 /*		const char *dtext;	/* null or diagnostic code */
18 /*		const char *mtype;	/* null or MTA type */
19 /*		const char *mname;	/* null or remote MTA */
20 /* .in -4
21 /*	} DSN;
22 /*
23 /*	DSN	*dsn_create(status, action, reason, dtype, dtext, mtype, mname)
24 /*	const char *status;
25 /*	const char *action;
26 /*	const char *reason;
27 /*	const char *dtype;
28 /*	const char *dtext;
29 /*	const char *mtype;
30 /*	const char *mname;
31 /*
32 /*	DSN	*DSN_COPY(dsn)
33 /*	DSN	*dsn;
34 /*
35 /*	void	dsn_free(dsn)
36 /*	DSN	*dsn;
37 /*
38 /*	DSN	*DSN_ASSIGN(dsn, status, action, reason, dtype, dtext,
39 /*						mtype, mname)
40 /*	DSN	*dsn;
41 /*	const char *status;
42 /*	const char *action;
43 /*	const char *reason;
44 /*	const char *dtype;
45 /*	const char *dtext;
46 /*	const char *mtype;
47 /*	const char *mname;
48 /*
49 /*	DSN	*DSN_SIMPLE(dsn, status, action, reason)
50 /*	DSN	*dsn;
51 /*	const char *status;
52 /*	const char *action;
53 /*	const char *reason;
54 /* DESCRIPTION
55 /*	This module maintains delivery error information. For a
56 /*	description of structure field members see "Arguments"
57 /*	below.  Function-like names spelled in upper case are macros.
58 /*	These may evaluate some arguments more than once.
59 /*
60 /*	dsn_create() creates a DSN structure and copies its arguments.
61 /*	The DSN structure should be destroyed with dsn_free().
62 /*
63 /*	DSN_COPY() creates a deep copy of its argument.
64 /*
65 /*	dsn_free() destroys a DSN structure and makes its storage
66 /*	available for reuse.
67 /*
68 /*	DSN_ASSIGN() updates a DSN structure and DOES NOT copy
69 /*	arguments or free memory.  The result DSN structure must
70 /*	NOT be passed to dsn_free(). DSN_ASSIGN() is typically used
71 /*	for stack-based short-lived storage.
72 /*
73 /*	DSN_SIMPLE() takes the minimally required subset of all the
74 /*	attributes and sets the rest to empty strings.
75 /*	This is a wrapper around the DSN_ASSIGN() macro.
76 /*
77 /*	Arguments:
78 /* .IP reason
79 /*	Human-readable text, used for logging purposes, and for
80 /*	updating the message-specific \fBbounce\fR or \fIdefer\fR
81 /*	logfile.
82 /* .IP status
83 /*	Enhanced status code as specified in RFC 3463.
84 /* .IP action
85 /*	DSN_NO_ACTION, empty string, or action as defined in RFC 3464.
86 /*	If no action is specified, a default action is chosen.
87 /* .IP dtype
88 /*	DSN_NO_DTYPE, empty string, or diagnostic code type as
89 /*	specified in RFC 3464.
90 /* .IP dtext
91 /*	DSN_NO_DTEXT, empty string, or diagnostic code as specified
92 /*	in RFC 3464.
93 /* .IP mtype
94 /*	DSN_NO_MTYPE, empty string, DSN_MTYPE_DNS or DSN_MTYPE_UNIX.
95 /* .IP mname
96 /*	DSN_NO_MNAME, empty string, or remote MTA as specified in
97 /*	RFC 3464.
98 /* DIAGNOSTICS
99 /*	Panic: null or empty status or reason.
100 /*	Fatal: out of memory.
101 /* LICENSE
102 /* .ad
103 /* .fi
104 /*	The Secure Mailer license must be distributed with this software.
105 /* AUTHOR(S)
106 /*	Wietse Venema
107 /*	IBM T.J. Watson Research
108 /*	P.O. Box 704
109 /*	Yorktown Heights, NY 10598, USA
110 /*--*/
111 
112 /* System library. */
113 
114 #include <sys_defs.h>
115 
116 /* Utility library. */
117 
118 #include <msg.h>
119 #include <mymalloc.h>
120 
121 /* Global library. */
122 
123 #include <dsn.h>
124 
125 /* dsn_create - create DSN structure */
126 
dsn_create(const char * status,const char * action,const char * reason,const char * dtype,const char * dtext,const char * mtype,const char * mname)127 DSN    *dsn_create(const char *status, const char *action, const char *reason,
128 		           const char *dtype, const char *dtext,
129 		           const char *mtype, const char *mname)
130 {
131     const char *myname = "dsn_create";
132     DSN    *dsn;
133 
134     dsn = (DSN *) mymalloc(sizeof(*dsn));
135 
136     /*
137      * Status and reason must not be empty. Other members may be empty
138      * strings.
139      *
140      * Early implementations represented unavailable information with null
141      * pointers. This resulted in code that was difficult to maintain. We now
142      * use empty strings instead. For safety sake we keep the null pointer
143      * test for input, but we always convert to empty string on output.
144      */
145 #define NULL_OR_EMPTY(s) ((s) == 0 || *(s) == 0)
146 
147     if (NULL_OR_EMPTY(status))
148 	msg_panic("%s: null dsn status", myname);
149     else
150 	dsn->status = mystrdup(status);
151 
152     if (NULL_OR_EMPTY(action))
153 	dsn->action = mystrdup("");
154     else
155 	dsn->action = mystrdup(action);
156 
157     if (NULL_OR_EMPTY(reason))
158 	msg_panic("%s: null dsn reason", myname);
159     else
160 	dsn->reason = mystrdup(reason);
161 
162     if (NULL_OR_EMPTY(dtype) || NULL_OR_EMPTY(dtext)) {
163 	dsn->dtype = mystrdup("");
164 	dsn->dtext = mystrdup("");
165     } else {
166 	dsn->dtype = mystrdup(dtype);
167 	dsn->dtext = mystrdup(dtext);
168     }
169     if (NULL_OR_EMPTY(mtype) || NULL_OR_EMPTY(mname)) {
170 	dsn->mtype = mystrdup("");
171 	dsn->mname = mystrdup("");
172     } else {
173 	dsn->mtype = mystrdup(mtype);
174 	dsn->mname = mystrdup(mname);
175     }
176     return (dsn);
177 }
178 
179 /* dsn_free - destroy DSN structure */
180 
dsn_free(DSN * dsn)181 void    dsn_free(DSN *dsn)
182 {
183     myfree((void *) dsn->status);
184     myfree((void *) dsn->action);
185     myfree((void *) dsn->reason);
186     myfree((void *) dsn->dtype);
187     myfree((void *) dsn->dtext);
188     myfree((void *) dsn->mtype);
189     myfree((void *) dsn->mname);
190     myfree((void *) dsn);
191 }
192