Postfix3.3.1
delivered_hdr.c
[詳解]
1 /*++
2 /* NAME
3 /* delivered_hdr 3
4 /* SUMMARY
5 /* process Delivered-To: headers
6 /* SYNOPSIS
7 /* #include <delivered_hdr.h>
8 /*
9 /* DELIVERED_HDR_INFO *delivered_hdr_init(stream, offset, flags)
10 /* VSTREAM *stream;
11 /* off_t offset;
12 /* int flags;
13 /*
14 /* int delivered_hdr_find(info, address)
15 /* DELIVERED_HDR_INFO *info;
16 /* const char *address;
17 /*
18 /* void delivered_hdr_free(info)
19 /* DELIVERED_HDR_INFO *info;
20 /* DESCRIPTION
21 /* This module processes addresses in Delivered-To: headers.
22 /* These headers are added by some mail delivery systems, for the
23 /* purpose of breaking mail forwarding loops. N.B. This solves
24 /* a different problem than the Received: hop count limit. Hop
25 /* counts are used to limit the impact of mail routing problems.
26 /*
27 /* delivered_hdr_init() extracts Delivered-To: header addresses
28 /* from the specified message, and returns a table with the
29 /* result. The file seek pointer is changed.
30 /*
31 /* delivered_hdr_find() looks up the address in the lookup table,
32 /* and returns non-zero when the address was found. The
33 /* address argument must be in internalized form.
34 /*
35 /* delivered_hdr_free() releases storage that was allocated by
36 /* delivered_hdr_init().
37 /*
38 /* Arguments:
39 /* .IP stream
40 /* The open queue file.
41 /* .IP offset
42 /* Offset of the first message content record.
43 /* .IP flags
44 /* Zero, or the bit-wise OR ot:
45 /* .RS
46 /* .IP FOLD_ADDR_USER
47 /* Case fold the address local part.
48 /* .IP FOLD_ADDR_HOST
49 /* Case fold the address domain part.
50 /* .IP FOLD_ADDR_ALL
51 /* Alias for (FOLD_ADDR_USER | FOLD_ADDR_HOST).
52 /* .RE
53 /* .IP info
54 /* Extracted Delivered-To: addresses information.
55 /* .IP address
56 /* A recipient address, internal form.
57 /* DIAGNOSTICS
58 /* Fatal errors: out of memory.
59 /* SEE ALSO
60 /* mail_copy(3), producer of Delivered-To: and other headers.
61 /* LICENSE
62 /* .ad
63 /* .fi
64 /* The Secure Mailer license must be distributed with this software.
65 /* AUTHOR(S)
66 /* Wietse Venema
67 /* IBM T.J. Watson Research
68 /* P.O. Box 704
69 /* Yorktown Heights, NY 10598, USA
70 /*--*/
71 
72 /* System library. */
73 
74 #include <sys_defs.h>
75 #include <unistd.h>
76 #include <string.h>
77 #include <ctype.h>
78 
79 /* Utility library. */
80 
81 #include <msg.h>
82 #include <mymalloc.h>
83 #include <htable.h>
84 #include <vstring.h>
85 #include <vstream.h>
86 #include <vstring_vstream.h>
87 #include <stringops.h>
88 
89 /* Global library. */
90 
91 #include <record.h>
92 #include <rec_type.h>
93 #include <is_header.h>
94 #include <quote_822_local.h>
95 #include <header_opts.h>
96 #include <delivered_hdr.h>
97 #include <fold_addr.h>
98 
99  /*
100  * Application-specific.
101  */
103  int flags;
107 };
108 
109 #define STR(x) vstring_str(x)
110 
111 /* delivered_hdr_init - extract delivered-to information from the message */
112 
113 DELIVERED_HDR_INFO *delivered_hdr_init(VSTREAM *fp, off_t offset, int flags)
114 {
115  char *cp;
116  DELIVERED_HDR_INFO *info;
117  const HEADER_OPTS *hdr;
118 
119  /*
120  * Sanity check.
121  */
122  info = (DELIVERED_HDR_INFO *) mymalloc(sizeof(*info));
123  info->flags = flags;
124  info->buf = vstring_alloc(10);
125  info->fold = vstring_alloc(10);
126  info->table = htable_create(0);
127 
128  if (vstream_fseek(fp, offset, SEEK_SET) < 0)
129  msg_fatal("seek queue file %s: %m", VSTREAM_PATH(fp));
130 
131  /*
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.
135  *
136  * XXX Don't get bogged down by gazillions of delivered-to headers.
137  */
138 #define DELIVERED_HDR_LIMIT 1000
139 
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  cp = fold_addr(info->fold, cp, info->flags);
149  if (msg_verbose)
150  msg_info("delivered_hdr_init: %s", cp);
151  htable_enter(info->table, cp, (void *) 0);
152  }
153  } else if (ISSPACE(STR(info->buf)[0])) {
154  continue;
155  } else {
156  break;
157  }
158  }
159  return (info);
160 }
161 
162 /* delivered_hdr_find - look up recipient in delivered table */
163 
164 int delivered_hdr_find(DELIVERED_HDR_INFO *info, const char *address)
165 {
166  HTABLE_INFO *ht;
167  const char *addr_key;
168 
169  /*
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.
173  */
174  quote_822_local(info->buf, address);
175  addr_key = fold_addr(info->fold, STR(info->buf), info->flags);
176  ht = htable_locate(info->table, addr_key);
177  return (ht != 0);
178 }
179 
180 /* delivered_hdr_free - destructor */
181 
183 {
184  vstring_free(info->buf);
185  vstring_free(info->fold);
186  htable_free(info->table, (void (*) (void *)) 0);
187  myfree((void *) info);
188 }
int msg_verbose
Definition: msg.c:177
void htable_free(HTABLE *table, void(*free_fn)(void *))
Definition: htable.c:287
void myfree(void *ptr)
Definition: mymalloc.c:207
HTABLE_INFO * htable_locate(HTABLE *table, const char *key)
Definition: htable.c:242
#define DELIVERED_HDR_LIMIT
ssize_t used
Definition: htable.h:27
int delivered_hdr_find(DELIVERED_HDR_INFO *info, const char *address)
#define VSTREAM_PATH(vp)
Definition: vstream.h:126
Definition: htable.h:25
const char * name
Definition: header_opts.h:17
HTABLE * htable_create(ssize_t size)
Definition: htable.c:179
#define is_header(str)
Definition: is_header.h:17
char * fold_addr(VSTRING *result, const char *addr, int flags)
Definition: fold_addr.c:67
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
DELIVERED_HDR_INFO * delivered_hdr_init(VSTREAM *fp, off_t offset, int flags)
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
off_t vstream_fseek(VSTREAM *stream, off_t offset, int whence)
Definition: vstream.c:1093
#define STR(x)
#define quote_822_local(dst, src)
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
#define HDR_DELIVERED_TO
Definition: header_opts.h:34
const HEADER_OPTS * header_opts_find(const char *string)
Definition: header_opts.c:156
#define REC_TYPE_NORM
Definition: rec_type.h:59
#define ISSPACE(c)
Definition: sys_defs.h:1753
#define rec_get(fp, buf, limit)
Definition: record.h:56
void delivered_hdr_free(DELIVERED_HDR_INFO *info)
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
HTABLE_INFO * htable_enter(HTABLE *table, const char *key, void *value)
Definition: htable.c:212
void msg_info(const char *fmt,...)
Definition: msg.c:199