Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / dsn.c
blob9f4185e3e944fd4d8feb8c7b4106d4442fa59eb8
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* dsn
6 /* SUMMARY
7 /* RFC-compliant delivery status information
8 /* SYNOPSIS
9 /* #include <dsn.h>
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;
23 /* 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;
32 /* DSN *DSN_COPY(dsn)
33 /* DSN *dsn;
35 /* void dsn_free(dsn)
36 /* DSN *dsn;
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;
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.
60 /* dsn_create() creates a DSN structure and copies its arguments.
61 /* The DSN structure should be destroyed with dsn_free().
63 /* DSN_COPY() creates a deep copy of its argument.
65 /* dsn_free() destroys a DSN structure and makes its storage
66 /* available for reuse.
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.
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.
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 /*--*/
112 /* System library. */
114 #include <sys_defs.h>
116 /* Utility library. */
118 #include <msg.h>
119 #include <mymalloc.h>
121 /* Global library. */
123 #include <dsn.h>
125 /* dsn_create - create DSN structure */
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)
131 const char *myname = "dsn_create";
132 DSN *dsn;
134 dsn = (DSN *) mymalloc(sizeof(*dsn));
137 * Status and reason must not be empty. Other members may be empty
138 * strings.
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.
145 #define NULL_OR_EMPTY(s) ((s) == 0 || *(s) == 0)
147 if (NULL_OR_EMPTY(status))
148 msg_panic("%s: null dsn status", myname);
149 else
150 dsn->status = mystrdup(status);
152 if (NULL_OR_EMPTY(action))
153 dsn->action = mystrdup("");
154 else
155 dsn->action = mystrdup(action);
157 if (NULL_OR_EMPTY(reason))
158 msg_panic("%s: null dsn reason", myname);
159 else
160 dsn->reason = mystrdup(reason);
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);
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);
176 return (dsn);
179 /* dsn_free - destroy DSN structure */
181 void dsn_free(DSN *dsn)
183 myfree((char *) dsn->status);
184 myfree((char *) dsn->action);
185 myfree((char *) dsn->reason);
186 myfree((char *) dsn->dtype);
187 myfree((char *) dsn->dtext);
188 myfree((char *) dsn->mtype);
189 myfree((char *) dsn->mname);
190 myfree((char *) dsn);