7 /* RFC-compliant delivery status information
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 */
23 /* DSN *create(status, action, reason, dtype, dtext, mtype, mname)
24 /* const char *status;
25 /* const char *action;
26 /* const char *reason;
38 /* DSN *DSN_ASSIGN(dsn, status, action, reason, dtype, dtext,
41 /* const char *status;
42 /* const char *action;
43 /* const char *reason;
49 /* DSN *DSN_SIMPLE(dsn, status, action, reason)
51 /* const char *status;
52 /* const char *action;
53 /* const char *reason;
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.
79 /* Human-readable text, used for logging purposes, and for
80 /* updating the message-specific \fBbounce\fR or \fIdefer\fR
83 /* Enhanced status code as specified in RFC 3463.
85 /* DSN_NO_ACTION, empty string, or action as defined in RFC 3464.
86 /* If no action is specified, a default action is chosen.
88 /* DSN_NO_DTYPE, empty string, or diagnostic code type as
89 /* specified in RFC 3464.
91 /* DSN_NO_DTEXT, empty string, or diagnostic code as specified
94 /* DSN_NO_MTYPE, empty string, DSN_MTYPE_DNS or DSN_MTYPE_UNIX.
96 /* DSN_NO_MNAME, empty string, or remote MTA as specified in
99 /* Panic: null or empty status or reason.
100 /* Fatal: out of memory.
104 /* The Secure Mailer license must be distributed with this software.
107 /* IBM T.J. Watson Research
109 /* Yorktown Heights, NY 10598, USA
112 /* System library. */
114 #include <sys_defs.h>
116 /* Utility library. */
119 #include <mymalloc.h>
121 /* Global library. */
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";
134 dsn
= (DSN
*) mymalloc(sizeof(*dsn
));
137 * Status and reason must not be empty. Other members may be empty
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
);
150 dsn
->status
= mystrdup(status
);
152 if (NULL_OR_EMPTY(action
))
153 dsn
->action
= mystrdup("");
155 dsn
->action
= mystrdup(action
);
157 if (NULL_OR_EMPTY(reason
))
158 msg_panic("%s: null dsn reason", myname
);
160 dsn
->reason
= mystrdup(reason
);
162 if (NULL_OR_EMPTY(dtype
) || NULL_OR_EMPTY(dtext
)) {
163 dsn
->dtype
= mystrdup("");
164 dsn
->dtext
= mystrdup("");
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("");
173 dsn
->mtype
= mystrdup(mtype
);
174 dsn
->mname
= mystrdup(mname
);
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
);