7 /* process Delivered-To: headers
9 /* #include <delivered_hdr.h>
11 /* DELIVERED_HDR_INFO *delivered_hdr_init(stream, offset, flags)
16 /* int delivered_hdr_find(info, address)
17 /* DELIVERED_HDR_INFO *info;
18 /* const char *address;
20 /* void delivered_hdr_free(info)
21 /* DELIVERED_HDR_INFO *info;
23 /* This module processes addresses in Delivered-To: headers.
24 /* These headers are added by some mail delivery systems, for the
25 /* purpose of breaking mail forwarding loops. N.B. This solves
26 /* a different problem than the Received: hop count limit. Hop
27 /* counts are used to limit the impact of mail routing problems.
29 /* delivered_hdr_init() extracts Delivered-To: header addresses
30 /* from the specified message, and returns a table with the
31 /* result. The file seek pointer is changed.
33 /* delivered_hdr_find() looks up the address in the lookup table,
34 /* and returns non-zero when the address was found. The
35 /* address argument must be in internalized form.
37 /* delivered_hdr_free() releases storage that was allocated by
38 /* delivered_hdr_init().
42 /* The open queue file.
44 /* Offset of the first message content record.
46 /* Zero, or the bit-wise OR ot:
49 /* Case fold the address local part.
51 /* Case fold the address domain part.
53 /* Alias for (FOLD_ADDR_USER | FOLD_ADDR_HOST).
56 /* Extracted Delivered-To: addresses information.
58 /* A recipient address, internal form.
60 /* Fatal errors: out of memory.
62 /* mail_copy(3), producer of Delivered-To: and other headers.
66 /* The Secure Mailer license must be distributed with this software.
69 /* IBM T.J. Watson Research
71 /* Yorktown Heights, NY 10598, USA
81 /* Utility library. */
88 #include <vstring_vstream.h>
89 #include <stringops.h>
95 #include <is_header.h>
96 #include <quote_822_local.h>
97 #include <header_opts.h>
98 #include <delivered_hdr.h>
99 #include <fold_addr.h>
102 * Application-specific.
104 struct DELIVERED_HDR_INFO
{
110 #define STR(x) vstring_str(x)
112 /* delivered_hdr_init - extract delivered-to information from the message */
114 DELIVERED_HDR_INFO
*delivered_hdr_init(VSTREAM
*fp
, off_t offset
, int flags
)
117 DELIVERED_HDR_INFO
*info
;
118 const HEADER_OPTS
*hdr
;
123 info
= (DELIVERED_HDR_INFO
*) mymalloc(sizeof(*info
));
125 info
->buf
= vstring_alloc(10);
126 info
->table
= htable_create(0);
128 if (vstream_fseek(fp
, offset
, SEEK_SET
) < 0)
129 msg_fatal("seek queue file %s: %m", VSTREAM_PATH(fp
));
132 * XXX Assume that mail_copy() produces delivered-to headers that fit in
133 * a REC_TYPE_NORM record. Lowercase the delivered-to addresses for
136 * XXX Don't get bogged down by gazillions of delivered-to headers.
138 #define DELIVERED_HDR_LIMIT 1000
140 while (rec_get(fp
, info
->buf
, 0) == REC_TYPE_NORM
141 && info
->table
->used
< DELIVERED_HDR_LIMIT
) {
142 if (is_header(STR(info
->buf
))) {
143 if ((hdr
= header_opts_find(STR(info
->buf
))) != 0
144 && hdr
->type
== HDR_DELIVERED_TO
) {
145 cp
= STR(info
->buf
) + strlen(hdr
->name
) + 1;
148 if (info
->flags
& FOLD_ADDR_ALL
)
149 fold_addr(cp
, info
->flags
);
151 msg_info("delivered_hdr_init: %s", cp
);
152 htable_enter(info
->table
, cp
, (char *) 0);
154 } else if (ISSPACE(STR(info
->buf
)[0])) {
163 /* delivered_hdr_find - look up recipient in delivered table */
165 int delivered_hdr_find(DELIVERED_HDR_INFO
*info
, const char *address
)
170 * mail_copy() uses quote_822_local() when writing the Delivered-To:
171 * header. We must therefore apply the same transformation when looking
172 * up the recipient. Lowercase the delivered-to address for consistency.
174 quote_822_local(info
->buf
, address
);
175 if (info
->flags
& FOLD_ADDR_ALL
)
176 fold_addr(STR(info
->buf
), info
->flags
);
177 ht
= htable_locate(info
->table
, STR(info
->buf
));
181 /* delivered_hdr_free - destructor */
183 void delivered_hdr_free(DELIVERED_HDR_INFO
*info
)
185 vstring_free(info
->buf
);
186 htable_free(info
->table
, (void (*) (char *)) 0);
187 myfree((char *) info
);