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