1#ifndef _DSN_H_INCLUDED_
2#define _DSN_H_INCLUDED_
3
4/*++
5/* NAME
6/*	dsn 3h
7/* SUMMARY
8/*	RFC-compliant delivery status information
9/* SYNOPSIS
10/*	#include <dsn.h>
11/* DESCRIPTION
12/* .nf
13
14 /*
15  * External interface.
16  */
17typedef struct {
18    const char *status;			/* RFC 3463 status */
19    const char *action;			/* Null / RFC 3464 action */
20    const char *reason;			/* descriptive reason */
21    const char *dtype;			/* Null / RFC 3464 diagnostic type */
22    const char *dtext;			/* Null / RFC 3464 diagnostic code */
23    const char *mtype;			/* Null / RFC 3464 MTA type */
24    const char *mname;			/* Null / RFC 3464 remote MTA */
25} DSN;
26
27extern DSN *dsn_create(const char *, const char *, const char *, const char *,
28		               const char *, const char *, const char *);
29extern void dsn_free(DSN *);
30
31#define DSN_ASSIGN(dsn, _status, _action, _reason, _dtype, _dtext, _mtype, _mname) \
32    (((dsn)->status = (_status)), \
33     ((dsn)->action = (_action)), \
34     ((dsn)->reason = (_reason)), \
35     ((dsn)->dtype = (_dtype)), \
36     ((dsn)->dtext = (_dtext)), \
37     ((dsn)->mtype = (_mtype)), \
38     ((dsn)->mname = (_mname)), \
39     (dsn))
40
41#define DSN_SIMPLE(dsn, _status, _reason) \
42    (((dsn)->status = (_status)), \
43     ((dsn)->action = DSN_NO_ACTION), \
44     ((dsn)->reason = (_reason)), \
45     ((dsn)->dtype = DSN_NO_DTYPE), \
46     ((dsn)->dtext = DSN_NO_DTEXT), \
47     ((dsn)->mtype = DSN_NO_MTYPE), \
48     ((dsn)->mname = DSN_NO_MNAME), \
49     (dsn))
50
51#define DSN_NO_ACTION	""
52#define DSN_NO_DTYPE	""
53#define DSN_NO_DTEXT	""
54#define DSN_NO_MTYPE	""
55#define DSN_NO_MNAME	""
56
57 /*
58  * Early implementations represented unavailable information with null
59  * pointers. This resulted in code that is hard to maintain. We now use
60  * empty strings instead. This does not waste precious memory as long as we
61  * can represent empty strings efficiently by collapsing them.
62  *
63  * The only restriction left is that the status and reason are never null or
64  * empty; this is enforced by dsn_create() which is invoked by DSN_COPY().
65  * This complicates the server reply parsing code in the smtp(8) and lmtp(8)
66  * clients. they must never supply empty strings for these required fields.
67  */
68#define DSN_COPY(dsn) \
69    dsn_create((dsn)->status, (dsn)->action, (dsn)->reason, \
70	(dsn)->dtype, (dsn)->dtext, \
71	(dsn)->mtype, (dsn)->mname)
72
73/* LICENSE
74/* .ad
75/* .fi
76/*	The Secure Mailer license must be distributed with this software.
77/* AUTHOR(S)
78/*	Wietse Venema
79/*	IBM T.J. Watson Research
80/*	P.O. Box 704
81/*	Yorktown Heights, NY 10598, USA
82/*--*/
83
84#endif
85