Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / delivered_hdr.c
blob6170f278fe824cd2eaf969bb0018eb345a57e8fa
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* delivered_hdr 3
6 /* SUMMARY
7 /* process Delivered-To: headers
8 /* SYNOPSIS
9 /* #include <delivered_hdr.h>
11 /* DELIVERED_HDR_INFO *delivered_hdr_init(stream, offset, flags)
12 /* VSTREAM *stream;
13 /* off_t offset;
14 /* int 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;
22 /* DESCRIPTION
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().
40 /* Arguments:
41 /* .IP stream
42 /* The open queue file.
43 /* .IP offset
44 /* Offset of the first message content record.
45 /* .IP flags
46 /* Zero, or the bit-wise OR ot:
47 /* .RS
48 /* .IP FOLD_ADDR_USER
49 /* Case fold the address local part.
50 /* .IP FOLD_ADDR_HOST
51 /* Case fold the address domain part.
52 /* .IP FOLD_ADDR_ALL
53 /* Alias for (FOLD_ADDR_USER | FOLD_ADDR_HOST).
54 /* .RE
55 /* .IP info
56 /* Extracted Delivered-To: addresses information.
57 /* .IP address
58 /* A recipient address, internal form.
59 /* DIAGNOSTICS
60 /* Fatal errors: out of memory.
61 /* SEE ALSO
62 /* mail_copy(3), producer of Delivered-To: and other headers.
63 /* LICENSE
64 /* .ad
65 /* .fi
66 /* The Secure Mailer license must be distributed with this software.
67 /* AUTHOR(S)
68 /* Wietse Venema
69 /* IBM T.J. Watson Research
70 /* P.O. Box 704
71 /* Yorktown Heights, NY 10598, USA
72 /*--*/
74 /* System library. */
76 #include <sys_defs.h>
77 #include <unistd.h>
78 #include <string.h>
79 #include <ctype.h>
81 /* Utility library. */
83 #include <msg.h>
84 #include <mymalloc.h>
85 #include <htable.h>
86 #include <vstring.h>
87 #include <vstream.h>
88 #include <vstring_vstream.h>
89 #include <stringops.h>
91 /* Global library. */
93 #include <record.h>
94 #include <rec_type.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 {
105 int flags;
106 VSTRING *buf;
107 HTABLE *table;
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)
116 char *cp;
117 DELIVERED_HDR_INFO *info;
118 const HEADER_OPTS *hdr;
121 * Sanity check.
123 info = (DELIVERED_HDR_INFO *) mymalloc(sizeof(*info));
124 info->flags = flags;
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
134 * consistency.
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;
146 while (ISSPACE(*cp))
147 cp++;
148 if (info->flags & FOLD_ADDR_ALL)
149 fold_addr(cp, info->flags);
150 if (msg_verbose)
151 msg_info("delivered_hdr_init: %s", cp);
152 htable_enter(info->table, cp, (char *) 0);
154 } else if (ISSPACE(STR(info->buf)[0])) {
155 continue;
156 } else {
157 break;
160 return (info);
163 /* delivered_hdr_find - look up recipient in delivered table */
165 int delivered_hdr_find(DELIVERED_HDR_INFO *info, const char *address)
167 HTABLE_INFO *ht;
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));
178 return (ht != 0);
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);