1 /*        $NetBSD: rec_type.h,v 1.4 2025/02/25 19:15:45 christos Exp $          */
2 
3 #ifndef _REC_TYPE_H_INCLUDED_
4 #define _REC_TYPE_H_INCLUDED_
5 
6 /*++
7 /* NAME
8 /*        rec_type 3h
9 /* SUMMARY
10 /*        Postfix record types
11 /* SYNOPSIS
12 /*        #include <rec_type.h>
13 /* DESCRIPTION
14 /* .nf
15 
16  /*
17   * System library.
18   */
19 #include <ctype.h>
20 #include <stdlib.h>
21 
22  /*
23   * Diagnostic codes, not real record lookup results.
24   */
25 #define REC_TYPE_EOF          -1                  /* no record */
26 #define REC_TYPE_ERROR        -2                  /* bad record */
27 
28  /*
29   * A queue file or IPC mail message consists of a sequence of typed records.
30   * The first record group contains time stamp, full name, sender envelope
31   * information, and optionally contains recipient information. The second
32   * record group contains data records with the message content. The last
33   * record group is optional; it contains information extracted from message
34   * headers, such as recipients, errors-to and return-receipt.
35   *
36   * Note: REC_TYPE_FILT and REC_TYPE_CONT are encoded with the same 'L'
37   * constant, and it  is too late to change that now.
38   */
39 #define REC_TYPE_SIZE         'C'                 /* first record, created by cleanup */
40 #define REC_TYPE_TIME         'T'                 /* arrival time, required */
41 #define REC_TYPE_CTIME        'c'                 /* create time, optional */
42 #define REC_TYPE_FULL         'F'                 /* full name, optional */
43 #define REC_TYPE_INSP         'I'                 /* inspector transport */
44 #define REC_TYPE_FILT         'L'                 /* loop filter transport */
45 #define REC_TYPE_FROM         'S'                 /* sender, required */
46 #define REC_TYPE_DONE         'D'                 /* delivered recipient, optional */
47 #define REC_TYPE_RCPT         'R'                 /* todo recipient, optional */
48 #define REC_TYPE_ORCP         'O'                 /* original recipient, optional */
49 #define REC_TYPE_DRCP         '/'                 /* canceled recipient, optional */
50 #define REC_TYPE_WARN         'W'                 /* warning message time */
51 #define REC_TYPE_ATTR         'A'                 /* named attribute for extensions */
52 #define REC_TYPE_KILL         'K'                 /* killed record */
53 
54 #define REC_TYPE_RDR          '>'                 /* redirect target */
55 #define REC_TYPE_FLGS         'f'                 /* cleanup processing flags */
56 #define REC_TYPE_DELAY        'd'                 /* cleanup delay upon arrival */
57 
58 #define REC_TYPE_MESG         'M'                 /* start message records */
59 
60 #define REC_TYPE_CONT         'L'                 /* long data record */
61 #define REC_TYPE_NORM         'N'                 /* normal data record */
62 #define REC_TYPE_DTXT         'w'                 /* padding (was: deleted data) */
63 
64 #define REC_TYPE_XTRA         'X'                 /* start extracted records */
65 
66 #define REC_TYPE_RRTO         'r'                 /* return-receipt, from headers */
67 #define REC_TYPE_ERTO         'e'                 /* errors-to, from headers */
68 #define REC_TYPE_PRIO         'P'                 /* priority */
69 #define REC_TYPE_PTR          'p'                 /* pointer indirection */
70 #define REC_TYPE_VERP         'V'                 /* VERP delimiters */
71 
72 #define REC_TYPE_DSN_RET      '<'       /* DSN full/hdrs */
73 #define REC_TYPE_DSN_ENVID    'i'       /* DSN envelope id */
74 #define REC_TYPE_DSN_ORCPT    'o'       /* DSN orig rcpt address */
75 #define REC_TYPE_DSN_NOTIFY   'n'       /* DSN notify flags */
76 
77 #define REC_TYPE_MILT_COUNT   'm'
78 
79 #define REC_TYPE_END          'E'                 /* terminator, required */
80 
81  /*
82   * What I expect to see in a "pure recipient" sequence at the end of the
83   * initial or extracted envelope segments, respectively. When a queue file
84   * contains pure recipient sequences only, then the queue manager will not
85   * have to read all the queue file records before starting delivery. This is
86   * often the case with list mail, where such optimization is desirable.
87   *
88   * XXX These definitions include the respective segment terminators to avoid
89   * special cases in the cleanup(8) envelope and extracted record processors.
90   */
91 #define REC_TYPE_ENV_RECIPIENT          "MDRO/Kon"
92 #define REC_TYPE_EXT_RECIPIENT          "EDRO/Kon"
93 
94  /*
95   * The types of records that I expect to see while processing different
96   * record groups. The first member in each set is the record type that
97   * indicates the end of that record group.
98   *
99   * XXX A records in the extracted segment are generated only by the cleanup
100   * server, and are not supposed to be present in locally submitted mail, as
101   * this is "postfix internal" information. However, the pickup server has to
102   * allow for the presence of A records in the extracted segment, because it
103   * can be requested to re-process already queued mail with `postsuper -r'.
104   *
105   * Note: REC_TYPE_FILT and REC_TYPE_CONT are encoded with the same 'L'
106   * constant, and it  is too late to change that now.
107   */
108 #define REC_TYPE_ENVELOPE     "MCTcFILSDRO/WVA>K<ion"
109 #define REC_TYPE_CONTENT      "XLNw"
110 #define REC_TYPE_EXTRACT      "EDRO/PreAFIL>Kon"
111 
112  /*
113   * The subset of inputs that the postdrop command allows.
114   */
115 #define REC_TYPE_POST_ENVELOPE          "MFSRVAin"
116 #define REC_TYPE_POST_CONTENT "XLN"
117 #define REC_TYPE_POST_EXTRACT "EAR"
118 
119  /*
120   * The record at the start of the queue file specifies the message content
121   * size (number of bytes between the REC_TYPE_MESG and REC_TYPE_XTRA meta
122   * records), data offset (offset of the first REC_TYPE_NORM or REC_TYPE_CONT
123   * text record), recipient count, and queue manager hints. These are all
124   * fixed-width fields so they can be updated in place. Queue manager hints
125   * are defined in qmgr_user.h
126   *
127   * See also: REC_TYPE_PTR_FORMAT below.
128   */
129 #define REC_TYPE_SIZE_FORMAT  "%15ld %15ld %15ld %15ld %15ld %15ld"
130 #define REC_TYPE_SIZE_CAST1   long      /* Vmailer extra offs - data offs */
131 #define REC_TYPE_SIZE_CAST2   long      /* Postfix 1.0 data offset */
132 #define REC_TYPE_SIZE_CAST3   long      /* Postfix 1.0 recipient count */
133 #define REC_TYPE_SIZE_CAST4   long      /* Postfix 2.1 qmgr flags */
134 #define REC_TYPE_SIZE_CAST5   long      /* Postfix 2.4 content length */
135 #define REC_TYPE_SIZE_CAST6   long      /* Postfix 3.0 smtputf8 flags */
136 
137  /*
138   * The warn record specifies when the next warning that the message was
139   * deferred should be sent.  It is updated in place by qmgr, so changing
140   * this value when there are deferred messages in the queue is dangerous!
141   */
142 #define REC_TYPE_WARN_FORMAT  "%15ld"   /* warning time format */
143 #define REC_TYPE_WARN_ARG(tv) ((long) (tv))
144 #define REC_TYPE_WARN_SCAN(cp, tv) ((tv) = atol(cp))
145 
146  /*
147   * Time information is not updated in place, but it does have complex
148   * formatting requirements, so we centralize things here.
149   */
150 #define REC_TYPE_TIME_FORMAT  "%ld %ld"
151 #define REC_TYPE_TIME_ARG(tv) (long) (tv).tv_sec, (long) (tv).tv_usec
152 #define REC_TYPE_TIME_SCAN(cp, tv) \
153     do { \
154           const char *_p = cp; \
155           (tv).tv_sec = atol(_p); \
156           while (ISDIGIT(*_p)) \
157               _p++; \
158           (tv).tv_usec = atol(_p); \
159     } while (0)
160 
161  /*
162   * Pointer records are used to edit a queue file in place before it is
163   * committed. When a record is appended or modified, we patch it into the
164   * existing record stream with a pointer to storage in a heap after the
165   * end-of-message marker; the new content is followed by a pointer record
166   * back to the existing record stream.
167   *
168   * We need to have a few dummy pointer records in place at strategic places
169   * (after the last recipient, after the last header) so that we can always
170   * append recipients or append/modify headers without having to move message
171   * segment terminators.
172   *
173   * We also need to have a dummy PTR record at the end of the content, so that
174   * we can always replace the message content without having to move the
175   * end-of-message marker.
176   *
177   * A dummy PTR record has a null argument.
178   *
179   * See also: REC_TYPE_SIZE_FORMAT above.
180   */
181 #define REC_TYPE_PTR_FORMAT   "%15ld"
182 #define REC_TYPE_PTR_PAYL_SIZE          15        /* Payload only, excludes record
183                                                    * header. */
184 
185  /*
186   * Programmatic interface.
187   */
188 extern const char *rec_type_name(int);
189 
190 /* LICENSE
191 /* .ad
192 /* .fi
193 /*        The Secure Mailer license must be distributed with this software.
194 /* AUTHOR(S)
195 /*        Wietse Venema
196 /*        IBM T.J. Watson Research
197 /*        P.O. Box 704
198 /*        Yorktown Heights, NY 10598, USA
199 /*--*/
200 
201 #endif
202